django Unique_together在字段为null时无效,如何约束它?

a8jjtwal  于 2023-05-30  发布在  Go
关注(0)|答案(1)|浏览(219)

我有一个这样的模型

class ProductCode( models.Model):
    class Meta:
        unique_together=[('code','customer'), ] 
    customer = models.ForeignKey( 'customers.Customer', models.CASCADE, null=True, blank=True, )
    code = models.CharField( max_length = 20)
    product = models.ForeignKey( Product, models.CASCADE, )
    ...

问题是如果customer is None(DB null),则不强制执行约束。它允许我多次使用(code ='foo',customer=None)存储行/对象。我发现了this SO post,这表明这个问题对于Postgres用户来说是不可修复的。
有没有办法用(相对)新的Metaconstraints来强制执行这个约束?我发现文件有点难以理解。
或者我必须实现一个占位符客户来附加“默认”产品代码?
或者,另一种方法是将customer的文本表示前置到code,然后将其设置为unique=True,并在必要时使用__startswith=__contains查找。

e5njpo68

e5njpo681#

这是预期行为:在数据库中,NULL非常特殊,因为NULL不等于NULL
您可以添加第二个唯一性约束,当另一个字段为NULL时使用,因此:

from django.db.models import Q

class ProductCode(models.Model):
    customer = models.ForeignKey(
        'customers.Customer',
        models.CASCADE,
        null=True,
        blank=True,
    )
    code = models.CharField(max_length=20)
    product = models.ForeignKey(
        Product,
        models.CASCADE,
    )

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=('code', 'customer'), name='code_customer_unique1'
            ),
            models.UniqueConstraint(
                fields=('code',),
                condition=Q(customer=None),
                name='code_customer_unique2',
            ),
        ]

注意:正如**unique_together[Django-doc]上的文档所说,unique_together约束可能会被弃用。文档建议使用Django的 constraint framework 中的UniqueConstraint**[Django-doc]。

相关问题