Opened 3 years ago

Last modified 3 years ago

#20611 new New feature

Add reverse unique field

Reported by: Anssi Kääriäinen Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Someday/Maybe
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


The idea is to add a model relation type by which one can query unique reverse relations. For example, if you have Article and ArticleTranslation then addition of "lang" restriction in the join from article to its translation makes the join unique.

There are multiple situations where such a system is useful: a computer can have multiple codes of different types, but for each code type the code value is unique. A room in hotel can have single active reservation per day.

The proposed patch adds a ReverseUnique(to_model, field_of_to_model, filters) model field. For examples see the branch, the test models and tests itself contain some example of why this would be useful.

A more generic but a bit harder to implement feature is allowing annotation of reverse unique values. There the idea would be that you could do:

   qs.annotate(translation_fi=ModelAnnotation(ArticleTranslation, through_field='article_translations', filter=Q(lang='fi')))

then you could use translation_fi like any relation. I think model level definition of the same thing will be useful in many cases (consider the active_translation case), so there is room for both model field implementation and annotation based implementation.

I will likely push the needed ORM & changes into 1.6 but leave other parts out. Pushing the changes to the new internal related field API seems OK to me.

Change History (5)

comment:1 Changed 3 years ago by Anssi Kääriäinen

Triage Stage: UnreviewedAccepted

Accepting my own ticket - I need it :) I will see if I can get the ORM changes still to 1.6.

comment:2 Changed 3 years ago by Anssi Kääriäinen

The ORM changes are really minor, and to a new API, so I will push these to both 1.6 and master. After that the ReverseUnique field can be implemented outside Django (although internal APIs must be used).

comment:3 Changed 3 years ago by Anssi Kääriäinen <akaariai@…>

In 6b4967e88368934dbbb1f289c790ab813fa59c72:

Minor change to get_extra_descriptor_filter()

Refs #20611.

comment:4 Changed 3 years ago by Anssi Kääriäinen <akaariai@…>

In 43f1d51b4ba3ab2c0223928904e1d24c0571da8d:

[1.6.x] Minor change to get_extra_descriptor_filter()

Refs #20611. Backpatch of 6b4967e88368934dbbb1f289c790ab813fa59c72.

comment:5 Changed 3 years ago by Anssi Kääriäinen

Triage Stage: AcceptedSomeday/Maybe

For those interested, an implementation exists at, lets see if this type of field will be useful enough for Django inclusion.

Note: See TracTickets for help on using tickets.
Back to Top