I have original question here How to access the names of fields in Django UniqueConstraint? but it do not answer my question when
*expressions
contains different kind of "fields". I left the accepted answer.
I want to access the unique constraint field names when declared in Meta class :
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"]
All fields are not necessarily a function like Lower
. In this case, author is a foreign key.
See https://docs.djangoproject.com/en/4.1/ref/models/constraints/
model._meta.constraints
constraint.fields
.expression.deconstruct()
method.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