Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#34296 closed Bug (duplicate)

Formset validation does not consider UniqueConstraint with F() expressions.

Reported by: Jannis Vajen Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: formset, constraints
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When saving a formset with data that violates the model's UniqueConstraint(), no form validation error is reported during formset.is_valid(). Instead an IntegrityError is raised during formset.save(). This only happens with the rather new UniqueConstraint(), the older method of using Meta.unique_together doesn't suffer from this.

Attachments (1)

unique_constraint.diff (2.0 KB ) - added by Jannis Vajen 2 years ago.
Test to reproduce the issue

Download all attachments as: .zip

Change History (5)

by Jannis Vajen, 2 years ago

Attachment: unique_constraint.diff added

Test to reproduce the issue

comment:1 by Jannis Vajen, 2 years ago

Version: 4.1dev

comment:2 by Mariusz Felisiak, 2 years ago

Resolution: duplicate
Status: newclosed
Summary: Formset validation does not consider models.UniqueConstraintFormset validation does not consider UniqueConstraint with F() expressions.
Triage Stage: UnreviewedAccepted

Thanks for the ticket. UniqueConstraint with expressions are ignored on purpose, see #33335, however we could include constraints that only use F()-expressions.

Duplicate of #23964.

comment:3 by Mariusz Felisiak, 2 years ago

As a workaround you can use fields instead of *expressions, e.g.

UniqueConstraint(fields=["poet", "name"], name="unique_together_poet_name")

comment:4 by Jannis Vajen, 2 years ago

Thank you, Mariusz. Using fields=[] works as expected.

If UniqueConstraints with expressions are excluded from validation on purpose, I wonder if this should be mentioned in the docs. It seems to me that the admonition you added in #33335

Validation of Constraints

In general constraints are not checked during full_clean(), and do not raise ValidationErrors. Rather you’ll get a database integrity error on save(). UniqueConstraints without a condition (i.e. non-partial unique constraints) and expressions (i.e. non-functional unique constraints) are different in this regard, in that they leverage the existing validate_unique() logic, and thus enable two-stage validation. In addition to IntegrityError on save(), ValidationError is also raised during model validation when the UniqueConstraint is violated.

still fully applies in 4.1, 4.2, and dev and should not have been removed during #30581

Validation of Constraints

Constraints are checked during the model validation.

Do you agree, or am I overlooking something?

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