Opened 3 years ago
Last modified 2 years ago
#33137 closed New feature
Decouple Field.unique from select_related — at Initial Version
Reported by: | Markus Holtermann | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | |
Severity: | Normal | Keywords: | |
Cc: | Simon Charette | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When inheriting from a OneToOneField
that automatically adds additional constraints to a model, the object-level relation might be a one-to-one relation, while the underlying implementation is still a many-to-one.
Let's say you have two models A
and B
where A.rel = MyOneToOneField(B)
and A.deleted = BooleanField()
. In a regular OneToOneField
there would now be a unique index on A.rel
. However, by adding a unique constraint to A._meta.constraints
over rel
with a condition on deleted=False
, rel
only needs to be unique among the "undeleted" objects. Doing so is possible by forcing MyOneToOneField.unique=False
(otherwise migrations create a constraint). However, this will mean, SQLCompiler.get_related_selections()
fails when trying to do B.objects.select_related("a")
, since a
is not a valid field. That is because SQLCompiler.get_related_selections._get_field_choices()
uses f.field.unique
instead of (f.field.many_to_one or f.field.one_to_one)
, I think. Because, essentially, opts.related_objects
is build based on those (many|one)_to_(many|one)
field attributes.