解决方案
我有原来的问题在这里如何访问Django uniqueconconstraint字段的名称?但是没有回答我的问题是
*expressions
何时包含不同类型的"字段"。
我想访问唯一的在Meta类中声明约束字段名:
class Book(models.Model):
name = CharField(...)
author = ForeignKey(...)
description = ...
class Meta:
constraints = [
UniqueConstraint(
Lower("name"), "author",
name="unique__book_author",
),
]
def do(self):
unique_fields = ... # should be ["name", "author"]
所有字段不一定是函数像Lower
。在本例中,author是一个外键。
见https://docs.djangoproject.com/en/4.1/ref/models/constraints/
创意
- 通过
model._meta.constraints
获取约束 - 过滤器唯一约束
- 对于每个唯一约束,执行以下操作
- 如果不包含表达式,请从
constraint.fields
获取字段名 - 否则,使用
expression.deconstruct()
方法从每个表达式中获取字段名。
- 如果不包含表达式,请从
解决方案from django.db import models
def get_unique_constraint_fields(model):
unique_constraints = (
c for c in model._meta.constraints
if isinstance(c, models.UniqueConstraint)
)
fields = []
for constraint in unique_constraints:
if not constraint.contains_expressions:
fields.extend(constraint.fields)
else:
for expression in constraint.expressions:
# deconstruct() returns (path, fields, kwargs)
_, (field, ), _ = expression.deconstruct()
fields.append(field)
return fields
from django.db import models
def get_unique_constraint_fields(model):
unique_constraints = (
c for c in model._meta.constraints
if isinstance(c, models.UniqueConstraint)
)
fields = []
for constraint in unique_constraints:
if not constraint.contains_expressions:
fields.extend(constraint.fields)
else:
for expression in constraint.expressions:
# deconstruct() returns (path, fields, kwargs)
_, (field, ), _ = expression.deconstruct()
fields.append(field)
return fields