Hello David, This is expected because Django doesn't have a way to express the constraint in words to present to the user when a condition, which could be complex, is provided.
When no conditions are defined the metadata is easy to interpret to form a sentence out of ("Foo with this field0, field1, fieldN already exists") while when a condition is provided Q can define very complex criteria that only the developer is able to express in words. This is the same class of problem as trying to have a machine describe a text representation of a regular expression. It's doable for very simple cases but almost impossible for complex ones. We decided not to try to be clever about what the error message should be and opted to have a default that uses the constraint name when a condition is present while allowing developers to provide a `violation_error_message` at constraint initialization to have them express what a more appropriate error message should be. If we take your particular example, how should Django figure out what the error message should be for a UniqueConstraint of this form? UniqueConstraint( fields=["foo"], name="unique_uppercase_foo", condition=Q(test__upper=F("test")) ) The developer who defined the constraint is in a much better position to provide an error that says that "Test with an upper case "foo" must be unique". If you're not convinced try with a complex condition involving OR and mixing transform comparison (e.g. a unique constraint only defined on palindromes) Cheers, Simon Le dimanche 11 septembre 2022 à 14:52:47 UTC-4, othnield...@gmail.com a écrit : > nice one there > > On Sun, Sep 11, 2022 at 3:36 PM David Sanders <shang.xia...@gmail.com> > wrote: > >> Hi folks (and in particular Simon Charette), >> >> I had a bit of a gotcha moment when a custom unique constraint validation >> message disappeared when I added a condition to it. I won't raise a ticket >> for this because it looks intentional from the constraint validation PR, >> but I wanted to seek clarification and whether either some adjustment to >> the behaviour could be made or clarification in the docs. >> >> Here's a boiled down example: >> >> Validating models with UniqueConstraint usually groups errors by field >> name: >> >> class Test(Model): >> test = CharField(max_length=255) >> >> class Meta: >> constraints = [ >> UniqueConstraint(fields=["test"], name="unique"), >> ] >> >> Test.objects.create(test="abc") >> test = Test(test="abc") >> test.validate_constraints() >> django.core.exceptions.ValidationError: {'test': ['Test with this Test >> already exists.']} >> >> However if a condition is added to the UniqueConstraint the validation >> error is categorised as a non-field error: >> >> class Test(Model): >> test = CharField(max_length=255) >> >> class Meta: >> constraints = [ >> UniqueConstraint(fields=["test"], name="unique", >> condition=~Q(test="")), >> ] >> >> Test.objects.create(test="abc") >> test = Test(test="abc") >> test.validate_constraints() >> django.core.exceptions.ValidationError: {'__all__': ['Constraint “unique” >> is violated.']} >> >> This affects the way custom error messages are defined (eg forms >> error_messages dict vs constraint violation_error_message) >> >> This behaviour is defined in UniqueConstraint.validate() and looks to be >> intentional from this advice from Simon: >> https://github.com/django/django/pull/14625#issuecomment-897275721 >> >> I was wondering what the rationale for that was? Would it be possible to >> make the behaviour consistent? And if not - would a PR to clarify how >> ValidationErrors are raised for constraints in the docs be welcomed? >> >> Cheers, >> David >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Django developers (Contributions to Django itself)" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to django-develop...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/django-developers/CADyZw-5w94wvx26OVdSaDHGjKxRGvdnCZYeMOM-p4J9t9JUqMw%40mail.gmail.com >> >> <https://groups.google.com/d/msgid/django-developers/CADyZw-5w94wvx26OVdSaDHGjKxRGvdnCZYeMOM-p4J9t9JUqMw%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/455d67d0-ca3e-4bc2-888f-10312dae8915n%40googlegroups.com.