﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
33137	Decouple Field.unique from select_related	Markus Holtermann	nobody	"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.

I think, what would fix the behavior, could be something like this:

{{{#!python
class SQLCompiler:
    def get_related_selections(self, select, opts=None, root_alias=None, cur_depth=1,
                               requested=None, restricted=None):
        def _get_field_choices():
            direct_choices = (f.name for f in opts.fields if f.is_relation)
            reverse_choices = (
                f.field.related_query_name()
                for f in opts.related_objects if (f.field.many_to_one or f.field.one_to_one)
            )
            return chain(direct_choices, reverse_choices, self.query._filtered_relations)
}}}"	New feature	closed	Database layer (models, ORM)		Normal	needsinfo		Simon Charette	Unreviewed	0	0	0	0	0	0
