I have model Foo which has field bar. The bar field should be unique, but allow nulls in it, meaning I want to allow more than one record if bar field is null
, but if it is not null
the values must be unique.
Here is my model:
class Foo(models.Model):
name = models.CharField(max_length=40)
bar = models.CharField(max_length=40, unique=True, blank=True, null=True, default=None)
And here is the corresponding SQL for the 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)
)
When using admin interface to create more than 1 foo objects where bar is null it gives me an error: "Foo with this Bar already exists."
However when I insert into database (PostgreSQL):
insert into appl_foo ("name", bar) values ('test1', null)
insert into appl_foo ("name", bar) values ('test2', null)
This works, just fine, it allows me to insert more than 1 record with bar being null, so the database allows me to do what I want, it's just something wrong with the Django model. Any ideas?
EDIT
The portability of the solution as far as DB is not an issue, we are happy with Postgres. I've tried setting unique to a callable, which was my function returning True/False for specific values of bar, it didn't give any errors, however seamed like it had no effect at all.
So far, I've removed the unique specifier from the bar property and handling the bar uniqueness in the application, however still looking for a more elegant solution. Any recommendations?
def get_db_prep_value(self, value, connection, prepared=False)
as method call. Check groups.google.com/d/msg/django-users/Z_AXgg2GCqs/zKEsfu33OZMJ for more informations. Following method works for me, too: def get_prep_value(self, value): if value=="": #if Django tries to save '' string, send the db None (NULL) return None else: return value #otherwise, just pass the value – Sitzmark