Ho il modello Foo che ha la barra di campo. Il campo della barra dovrebbe essere univoco, ma consentire valori nulli al suo interno, il che significa che voglio consentire più di un record se il campo della barra lo è null
, ma se non lo è null
i valori devono essere univoci.
Ecco il mio modello:
class Foo(models.Model):
name = models.CharField(max_length=40)
bar = models.CharField(max_length=40, unique=True, blank=True, null=True, default=None)
Ed ecco l'SQL corrispondente per la tabella:
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)
)
Quando si utilizza l'interfaccia di amministrazione per creare più di 1 oggetti foo in cui la barra è nulla mi dà un errore: "Foo con questa barra esiste già".
Tuttavia, quando inserisco nel database (PostgreSQL):
insert into appl_foo ("name", bar) values ('test1', null)
insert into appl_foo ("name", bar) values ('test2', null)
Funziona bene, mi permette di inserire più di 1 record con la barra nulla, quindi il database mi permette di fare quello che voglio, è solo qualcosa di sbagliato nel modello Django. Qualche idea?
MODIFICARE
La portabilità della soluzione per quanto DB non sia un problema, siamo contenti di Postgres. Ho provato a impostare l'esclusivo su un callable, che era la mia funzione che restituiva True / False per valori specifici di bar , non dava alcun errore, tuttavia era aggraffato come se non avesse alcun effetto.
Finora, ho rimosso l'identificatore univoco dalla proprietà bar e gestendo l' unicità della barra nell'applicazione, tuttavia sto ancora cercando una soluzione più elegante. Qualche consiglio?
def get_db_prep_value(self, value, connection, prepared=False)
come metodo di chiamata. Controlla gruppi.google.com/d/msg/django-users/Z_AXgg2GCqs/zKEsfu33OZMJ per ulteriori informazioni. Il seguente metodo funziona anche per me: def get_prep_value (self, value): if value == "": #if Django prova a salvare '' stringa, invia il db None (NULL) return Nient'altro: valore restituito # altrimenti, solo passare il valore