我有一个 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