标签: django-constraints

使用带有注释的 Django CheckConstraint

我有一个 Django 模型,其中每个实例都需要一个从三个字段派生的唯一标识符:

class Example(Model):
    type = CharField(blank=False, null=False)           # either 'A' or 'B'
    timestamp = DateTimeField(default=timezone.now)
    number = models.IntegerField(null=True)             # a sequential number
Run Code Online (Sandbox Code Playgroud)

这会产生一个形式为 的标签,[type][timestamp YEAR][number]除非number为空,否则它必须是唯一的。

我想我可以使用几个注释:

uid_expr = Case(
    When(
        number=None,
        then=Value(None),
    ),
    default=Concat(
        'type', ExtractYear('timestamp'), 'number',
        output_field=models.CharField()
    ),
    output_field=models.CharField()
)

uid_count_expr = Count('uid', distinct=True)
Run Code Online (Sandbox Code Playgroud)

get_queryset默认情况下,我覆盖了模型的管理器以应用注释,然后尝试使用CheckConstraint

class Example(Model):
    ...

    class Meta:
        constraints = [
            models.CheckConstraint(check=Q(uid_cnt=1), name='unique_uid')
        ]
Run Code Online (Sandbox Code Playgroud)

这失败了,因为它无法在名为 的实例上找到一个字段uid_cnt,但是我认为Q对象可以访问注释。它看起来像是CheckConstraint直接针对模型进行查询,而不是使用管理器返回的查询集:

class CheckConstraint(BaseConstraint):
    ...

    def _get_check_sql(self, model, …
Run Code Online (Sandbox Code Playgroud)

django django-models django-queryset django-q django-constraints

8
推荐指数
1
解决办法
318
查看次数