Add reverse unique field
|Reported by:||Anssi Kääriäinen||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||master|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||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 https://github.com/akaariai/django/compare/reverse_unique, 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 & related.py changes into 1.6 but leave other parts out. Pushing the changes to the new internal related field API seems OK to me.