Opened 20 months ago

Last modified 7 days ago

#34007 assigned Cleanup/optimization

Single-field conditional UniqueContraint validation errors are classified as non-field-errors

Reported by: David Sanders Owned by: David Sanders
Component: Database layer (models, ORM) Version: 4.1
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Mailing list discussion with Simon Charette: https://groups.google.com/g/django-developers/c/7QGy6i9oe4g/m/iCJE7be0AgAJ

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.']}

My proposal is to make the validation error a field-error for any unique constraint that only has a single field defined.

This affects the way custom error messages are defined (eg forms error_messages dict vs constraint violation_error_message).

It's been agreed that the error message wording should remain the generic "Constraint is violated" format as determining the correct wording involving conditions is non-trivial.

Change History (6)

comment:2 by David Sanders, 20 months ago

Has patch: set

comment:3 by Mariusz Felisiak, 20 months ago

Component: UncategorizedDatabase layer (models, ORM)
Owner: changed from nobody to David Sanders
Status: newassigned
Summary: Single-field conditional UniqueContraint validation errors are clasified as non-field-errorsSingle-field conditional UniqueContraint validation errors are classified as non-field-errors
Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization

comment:4 by Mariusz Felisiak, 20 months ago

Patch needs improvement: set

comment:5 by Sarah Boyce <42296566+sarahboyce@…>, 8 days ago

In 97d48cd:

Refs #34007, Refs #35359 -- Added Q.referenced_based_fields property.

Thank you to Mariusz Felisiak and Natalia Bidart for the reviews.

comment:6 by Natalia <124304+nessita@…>, 7 days ago

In fa202d5c:

[5.0.x] Refs #34007, Refs #35359 -- Added Q.referenced_based_fields property.

Thank you to Mariusz Felisiak and Natalia Bidart for the reviews.

Backport of 97d48cd3c6f409584b5cc19fbddfca917bae78fd from main

Note: See TracTickets for help on using tickets.
Back to Top