ran*_*ndy 3 django django-models
unique_together
不起作用,它只在第一个字段上设置唯一约束并忽略第二个字段。有没有办法强制执行唯一约束?
class BaseModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
deleted = models.DateTimeField(db_index=True, null=True, blank=True)
last_modified_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Book(BaseModel):
first_form_number = models.CharField(max_length=8)
class Meta:
unique_together = (("first_form_number", "deleted"),)
Run Code Online (Sandbox Code Playgroud)
您的模型在创建正确的唯一索引的范围内正常工作:
$ python manage.py sqlmigrate app 0001_initial
...
CREATE UNIQUE INDEX "app_base_slug_version_a455c5b7_uniq" ON "app_base" ("slug", "version");
...
Run Code Online (Sandbox Code Playgroud)
(预计您的应用程序名称是“app”)
我必须大致同意 user3541631 的回答。这通常取决于数据库,但 Django 直接支持的所有四个数据库引擎都相似。他们期望“空值在 UNIQUE 列中是不同的”(请参阅SQLite 与其他数据库引擎中的 NULL 处理)
我验证了您的问题是否为空:
class Test(TestCase):
def test_without_null(self):
timestamp = datetime.datetime(2017, 8, 25, tzinfo=pytz.UTC)
book_1 = Book.objects.create(deleted=timestamp, first_form_number='a')
with self.assertRaises(django.db.utils.IntegrityError):
Book.objects.create(deleted=timestamp, first_form_number='a')
def test_with_null(self):
# this test fails !!! (and a duplicate is created)
book_1 = Book.objects.create(first_form_number='a')
with self.assertRaises(django.db.utils.IntegrityError):
Book.objects.create(first_form_number='a')
Run Code Online (Sandbox Code Playgroud)
如果您愿意手动编写迁移以创建两个特殊的部分唯一索引,则可以为PostgreSQL 提供一个解决方案:
CREATE UNIQUE INDEX book_2col_uni_idx ON app_book (first_form_number, deleted)
WHERE deleted IS NOT NULL;
CREATE UNIQUE INDEX book_1col_uni_idx ON app_book (first_form_number)
WHERE deleted IS NULL;
Run Code Online (Sandbox Code Playgroud)
看:
归档时间: |
|
查看次数: |
2194 次 |
最近记录: |