Il s'agit d'une décision de conception SQL.
SQL 2011 draft, à la page 474 se lit comme suit:
S'il n'y a pas deux lignes de T de telle sorte que la valeur de chaque colonne dans une rangée est non-nulle et ne se distingue pas de la valeur de la colonne correspondante dans l'autre rangée, le résultat est True; sinon, le résultat de la est False.
Cela signifie que deux valeurs NULL sont considérées comme distinctes lorsqu'il s'agit de la contrainte unique. Ceci contredit la définition du type de données NULL à la page 41:
Deux valeurs nulles ne sont pas distinctes.
Une valeur nulle et une valeur non nulle sont distinctes.
Deux valeurs non nulles sont distinctes si les règles générales du sous-paragraphe 8.15, «», renvoient Vrai.
Règles générales de 8.15 dit Le paragraphe:
Si les deux V1 et V2 sont la valeur nulle, alors le résultat est faux.
Pour résumer:
En ce qui concerne le type de données, le "caractère distinctif" des deux est nulls sens Faux NULL == NULL.
Mais la contrainte unique au niveau de la table indique autrement: NULL! = NULL. Il peut y avoir plusieurs valeurs NULL dans un champ d'une table qui indique qu'elles doivent être uniques.
Le suivi de ticket Django est #1751 unique_together does not work when any of the listed fields contains a FK. La solution de contournement consiste à définir votre propre méthode de modèle .validate_unique
comme mentionné dans le documentation. Le select_for_update
crée un verrou pour éviter une condition de concurrence.
Cette solution fonctionne pour les soumissions de formulaire, elle ne fonctionne pas lors de l'accès direct à la méthode Genre.objects.create()
. Dans cette situation, vous devez créer l'instance Genre
en trois étapes:
genre = Genre(id='id1')
genre.validate_unique()
genre.save()