Problem
I have a Django model :
The
But when I do:
Solution:
try this solution
I have a Django model :
class QuestionAnswer(models.Model):
question = models.ForeignKey(Question)
marks = models.FloatField(null=True)
graded = models.IntegerField()
Now in command line I do:
>>> qa = QuestionAnswer.objects.filter(pk=12345)
>>> qa[0].graded
0
>>> qa[0].graded = 1
>>> qa[0].save()
>>> qa = QuestionAnswer.objects.filter(pk=12345)
>>> qa.graded
0
graded
field is not updated.But when I do:
>>> qa = QuestionAnswer.objects.get(pk=12345)
>>> qa.graded
0
>>> qa.graded = 1
>>> qa.save()
>>> qa = QuestionAnswer.objects.get(pk=12345)
>>> qa.graded
1
Why does objects.filter
not updating the field but objects.get
works.Solution:
try this solution
>>> qs = QuestionAnswer.objects.filter(pk=12345)
>>> qa = qs[0]
>>> qa.graded
0
>>> qa.graded = 1
>>> qa.save()
>>> qa = QuestionAnswer.objects.filter(pk=12345)
>>> qa[0].graded
This should be 1
By using
qa[0]
, you're not actually modifying and saving the same object (even though they represent the same SQL data).
This is due to the fact that querysets are lazy: they only execute the sql query when you actually try to use the data that the queryset would return. The way slices work with querysets, the query is executed but the result will not be cached. This means that whenever you use
qa[0]
, a new query is executed, and that data is saved in a newly created model instance. What you are effectively doing is this:>>> qs = QuestionAnswer.objects.filter(pk=12345)
>>> qa1 = qs.get()
>>> qa1.graded
0
>>> qa2 = qs.get()
>>> qa2.graded = 1
>>> qa3 = qs.get()
>>> qa3.save()
It should be obvious that
However, if you were to evaluate the entire queryset before slicing, all results would be cached, and the following would work:
qa1
, qa2
and qa3
are different instances of your model: while they have the same attribute values (as the represent the same database data), they are actually saved in different places in memory and are completely separate from each other. Changing the graded
attribute on qa2
will not in any way affect qa3
, so when qa3
is saved, the changes to qa2
won't be reflected in the changes in the database.However, if you were to evaluate the entire queryset before slicing, all results would be cached, and the following would work:
>>> qs = QuestionAnswer.objects.filter(pk=12345)
>>> qs[0] is qs[0]
False # These are not the same objects in memory...
>>> bool(qs) # This forces evaluation of the entire queryset
True
>>> qs[0] is qs[0]
True # ... but these are!
>>> qs[0].graded
0
>>> qs[0].graded = 1
>>> qs[0].save()
>>> qs = QuestionAnswer.objects.filter(pk=12345)
>>> qs[0].graded
1
TO see in Detail about Dejnago queries visit django queries in detail
No comments:
Post a Comment