J'ai le modèle Foo qui a une barre de champ. Le champ de la barre doit être unique, mais autoriser les valeurs nulles, ce qui signifie que je souhaite autoriser plus d'un enregistrement si le champ de la barre l'est null
, mais si ce n'est pas null
le cas, les valeurs doivent être uniques.
Voici mon modèle:
class Foo(models.Model):
name = models.CharField(max_length=40)
bar = models.CharField(max_length=40, unique=True, blank=True, null=True, default=None)
Et voici le SQL correspondant pour la table:
CREATE TABLE appl_foo
(
id serial NOT NULL,
"name" character varying(40) NOT NULL,
bar character varying(40),
CONSTRAINT appl_foo_pkey PRIMARY KEY (id),
CONSTRAINT appl_foo_bar_key UNIQUE (bar)
)
Lorsque vous utilisez l'interface d'administration pour créer plus de 1 objets foo où bar est nul, cela me donne une erreur: "Foo avec cette barre existe déjà."
Cependant, lorsque j'insère dans la base de données (PostgreSQL):
insert into appl_foo ("name", bar) values ('test1', null)
insert into appl_foo ("name", bar) values ('test2', null)
Cela fonctionne, très bien, cela me permet d'insérer plus d'un enregistrement avec une barre nulle, donc la base de données me permet de faire ce que je veux, c'est juste quelque chose qui ne va pas avec le modèle Django. Des idées?
ÉDITER
La portabilité de la solution dans la mesure où DB n'est pas un problème, nous sommes satisfaits de Postgres. J'ai essayé de définir un paramètre unique pour un appelable, qui était ma fonction retournant Vrai / Faux pour des valeurs spécifiques de barre , cela ne donnait aucune erreur, même si cela n'avait aucun effet.
Jusqu'à présent, j'ai supprimé le spécificateur unique de la propriété bar et géré l' unicité de la barre dans l'application, tout en recherchant une solution plus élégante. Des recommandations?
def get_db_prep_value(self, value, connection, prepared=False)
d'un appel de méthode. Consultez groups.google.com/d/msg/django-users/Z_AXgg2GCqs/zKEsfu33OZMJ pour plus d'informations. La méthode suivante fonctionne aussi pour moi: def get_prep_value (self, value): if value == "": #if Django essaie de sauvegarder la chaîne '', envoie la base de données None (NULL) return None else: renvoie la valeur #otherwise, juste passer la valeur