1

Accepted answer for original question. Still not OK for "edit 1" (below)


Original Question

I want to access the field names when declared in Meta class :

class Book(models.Model):
    name = CharField(...)
    author = CharField(...)

    class Meta:
        constraints = [
            UniqueConstraint(
                # fields=['name', 'author'],       # solution 1
                Lower("name"), Lower("author"),    # solution 2
                name="unique__book_author",
            ),
        ]

With solution 1, I access with Book._meta.constraints[0].fields => ('name', 'author').

With solution 2, Book._meta.constraints[0].fields is empty :'(

Any idea ?

See https://docs.djangoproject.com/en/4.1/ref/models/constraints/


edit 1

All fields are not necessarily a function like Lower. If "author" is not a CharField but FKField, *expressions could be :

UniqueConstraint(Lower("name"), "author", name="unique__book_author")
cedrik
  • 541
  • 7
  • 17

1 Answers1

0

Give this a try:

fileds = []
for expression in Book._meta.constraints[0].expressions:
    fields.append(expression.lhs.name)

print(fileds)
# Output: ['name', 'author']

Update

to get the constraints that are not expressions try this

filed_names = Book._meta.constraints[0].columns
Sumithran
  • 6,217
  • 4
  • 40
  • 54
  • Well. I have to say hat it _almost_ works. I just had to remove `target`. Maybe you could edit your answer so I can accept your answer ? But I'm not entirely satisfyed :)... if one of the expression is not a "function" (like `Lower`), then `lhs` porperty raises `AttributeError: 'F' object has no attribute 'lhs'` – cedrik Mar 31 '23 at 07:23
  • i have update the answer, if the expression is not an expression then it would appear in Book._meta.constraints[0].fields, so you would have to append results of both _meta.constrains.[0] and _meta.constraints[0].expressions – Sumithran Mar 31 '23 at 07:55
  • Well, with `UniqueConstraint(Lower("name"), "author", name="unique__book_author")`I get `Book._meta.constraints[0].fields == ()` and `Book._meta.constraints[0].expressions == (Lower(F(name)), F(author))`. I miss something ? – cedrik Mar 31 '23 at 09:08