Saya memiliki model Foo yang memiliki kolom bar. Bidang batang harus unik, tetapi memungkinkan null di dalamnya, yang berarti saya ingin mengizinkan lebih dari satu catatan jika bidang batang adalah null
, tetapi jika tidak null
, nilainya harus unik.
Ini model saya:
class Foo(models.Model):
name = models.CharField(max_length=40)
bar = models.CharField(max_length=40, unique=True, blank=True, null=True, default=None)
Dan berikut adalah SQL yang sesuai untuk tabel:
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)
)
Saat menggunakan antarmuka admin untuk membuat lebih dari 1 objek foo dengan bilah nol, ini memberi saya kesalahan: "Foo dengan bilah ini sudah ada."
Namun ketika saya memasukkan ke dalam database (PostgreSQL):
insert into appl_foo ("name", bar) values ('test1', null)
insert into appl_foo ("name", bar) values ('test2', null)
Ini berfungsi, baik-baik saja, ini mengijinkan saya untuk memasukkan lebih dari 1 catatan dengan bar menjadi null, jadi database memperbolehkan saya untuk melakukan apa yang saya inginkan, itu hanya sesuatu yang salah dengan model Django. Ada ide?
EDIT
Portabilitas solusi sejauh DB tidak menjadi masalah, kami senang dengan Postgres. Saya sudah mencoba mengatur unique to a callable, yaitu fungsi saya mengembalikan True / False untuk nilai tertentu dari bar , itu tidak memberikan kesalahan apa pun, namun seamed seperti itu tidak berpengaruh sama sekali.
Sejauh ini, saya telah menghapus specifier unik dari properti bar dan menangani keunikan bar dalam aplikasi, namun tetap mencari solusi yang lebih elegan. Ada rekomendasi?
def get_db_prep_value(self, value, connection, prepared=False)
sebagai pemanggilan metode. Periksa groups.google.com/d/msg/django-users/Z_AXgg2GCqs/zKEsfu33OZMJ untuk informasi lebih lanjut. Metode berikut juga bekerja untuk saya: def get_prep_value (self, value): if value == "": # jika Django mencoba menyimpan '' string, kirim db None (NULL) return None else: return value #otherwise, just lulus nilai