J'ai un modèle Foo qui a un champ bar. Le champ bar doit être unique, mais il peut contenir des nuls, ce qui signifie que je veux autoriser plus d'un enregistrement si le champ bar a la valeur suivante null
mais si ce n'est pas le cas null
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 j'utilise l'interface d'administration pour créer plus d'un objet foo où bar est nul, je reçois 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 la barre étant 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. Avez-vous une idée ?
EDIT
La portabilité de la solution en ce qui concerne la base de données n'est pas un problème, nous sommes satisfaits de Postgres. J'ai essayé de mettre unique à un callable, qui était ma fonction retournant Vrai/Faux pour des valeurs spécifiques de bar Il n'y a pas eu d'erreur, mais il semble que cela n'ait pas eu d'effet du tout.
Jusqu'à présent, j'ai supprimé le spécificateur unique de l'option bar et le traitement de la propriété bar l'unicité de l'application, mais je suis toujours à la recherche d'une solution plus élégante. Des recommandations ?
0 votes
Je ne peux pas encore faire de commentaires, alors voici un petit complément à l'original : Depuis Django 1.4, vous devez avoir
def get_db_prep_value(self, value, connection, prepared=False)
comme appel de méthode. Vérifiez 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=="" : #Si Django essaie de sauvegarder la chaîne '', envoyer à la base de données None (NULL) return None else : return value #autrement, passer simplement la valeur0 votes
J'ai ouvert un ticket Django pour cela. Ajoutez votre soutien. code.djangoproject.com/ticket/30210#ticket