Is it possible to refresh the state of a django object from database? I mean behavior roughly equivalent to:
new_self = self.__class__.objects.get(pk=self.pk)
for each field of the record:
setattr(self, field, getattr(new_self, field))
UPDATE: Found a reopen/wontfix war in the tracker: http://code.djangoproject.com/ticket/901. Still don't understand why the maintainers don't like this.
commmit
. Once you've done that, you'd have to wait around for the next SQL transaction to commit. Why do that? How long are you going to wait for the next transaction?
As of Django 1.8 refreshing objects is built in. Link to docs.
def test_update_result(self):
obj = MyModel.objects.create(val=1)
MyModel.objects.filter(pk=obj.pk).update(val=F('val') + 1)
# At this point obj.val is still 1, but the value in the database
# was updated to 2. The object's updated value needs to be reloaded
# from the database.
obj.refresh_from_db()
self.assertEqual(obj.val, 2)
I've found it relatively easy to reload the object from the database like so:
x = X.objects.get(id=x.id)
refresh_from_db
solves all these problems.
As @Flimm pointed out, this is a really awesome solution:
foo.refresh_from_db()
This reloads all data from the database into the object.
In reference to @grep's comment, shouldn't it be possible to do:
# Put this on your base model (or monkey patch it onto django's Model if that's your thing)
def reload(self):
new_self = self.__class__.objects.get(pk=self.pk)
# You may want to clear out the old dict first or perform a selective merge
self.__dict__.update(new_self.__dict__)
# Use it like this
bar.foo = foo
assert bar.foo.pk is None
foo.save()
foo.reload()
assert bar.foo is foo and bar.foo.pk is not None
refresh_from_db
method.
Success story sharing
refresh_from_db
will only update such already populated fields.DoesNotExist
exception if the underlying object was deleted when callingrefresh_from_db
. FYI.