Unify reverse foreign key and m2m querying behavior
|Reported by:||akaariai||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||master|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||yes|
Currently when querying unsaved reverse relations the behavior differs.
class Foo(models.Model): fk = models.ForeignKey('self', related_name='fk_rev') m2m = models.ManyToManyField('self')
and test case:
We get  from the first filter, but an error
ValueError: "<Foo: Foo object>" needs to have a value for field "from_foo" before this many-to-many relationship can be used.
from the second filter.
So, m2m fields can't be filtered if the object isn't saved, but reverse fk fields can be filtered.
There is a (slightly stale) patch for #17541 which makes fk fields and m2m fields work consistently. The changes in behavior are:
* Nullable many-to-many and foreign key relations will return an empty queryset when the relation field is null. For many-to-many this was previously an error (no change for foreign keys). * Trying to add objects to a foreign key relation when the relation field is null is now an error (no change for m2m). * Trying to use a relation of any kind when the object isn't saved is now an error (no change for m2m).
I think we can squeeze these changes in as bug-fixes. These are slight backwards compatibility changes, but to me it seems that almost always the changes will be visible only in code that isn't working as intended. If these are seen as something likely breaking working code, then I don't see any way to make the APIs consistent.
The #17541 patch is available from: https://github.com/akaariai/django/compare/ticket_17541
Change History (2)
comment:1 Changed 2 years ago by akaariai
- Needs documentation unset
- Needs tests unset
- Patch needs improvement set
- Triage Stage changed from Unreviewed to Design decision needed
- Type changed from Uncategorized to Cleanup/optimization
- Version changed from 1.4 to master