I was going through ORM tickets marked ready for checkin and stumbled
upon ticket #14368. The ticket is about caching of o2o fields. The
interesting part is not the caching, but this functionality:
class A:
pass
class B:
a = O2O(A, null=True, related_name='b')
a1 = A.save()
b1 = B.save()
# The below does not do a save currently.
a1.b = b1
# But after the patch there is an implicit save of b1
The implicit save is implemented because there is a similar
functionality for ForeinKeys:
>>> someobj.reverse_fk_set = RelatedObj.objects.all()
What happens is that the RelatedObj.objects.all() queryset is
iterated, and each object of the queryset is saved with the fk changed
to point to the someobj. An implicit save again.
Now, I don't like the implicit saves at all. A variable assignment
should not cause a database save. So, I would like to deprecate the
current behavior. Assignment to reverse_fk_set (and I guess this goes
for m2m, too) is no longer allowed. Instead you will need to
explicitly do:
>>> someobj.reverse_fk_set.set(RelatedObj.objects.all())
Now you are calling a method, and saving in this situation is OK and
analogous to other related manager methods.
Lets raise a deprecation warning on direct assignment to the
reverse_fk_set and remove it then in 1.7. The message would be
something like "Direct assignment to the reverse side of a related set
is deprecated. Use .set() instead. See ... for more details."
A related thread discussing this same issue:
http://groups.google.com/group/django-developers/tree/browse_frm/thread/634499444687556f#doc_f1a254e8bf4ad8d9
Comments?
- Anssi