#35676: ExclusionConstraint that includes a ForeignKey fails validation in ModelForm ------------------------------+------------------------------------ Reporter: Take Weiland | Owner: (none) Type: Bug | Status: new Component: Forms | Version: 5.1 Severity: Normal | Resolution: Keywords: | Triage Stage: Accepted Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 ------------------------------+------------------------------------ Changes (by Simon Charette):
* component: Uncategorized => Forms * stage: Unreviewed => Accepted * type: Uncategorized => Bug Comment: Thanks for the detailed report. [https://github.com/django/django/blob/b99c608ea10cabc97a6b251cdb6e81ef2a83bdcf/django/forms/models.py#L477-L488 The comment you pointed at] makes it clear that this is a variant of #12960 but for constraints instead of uniques. I think something along the following lines should address the issue but I'm curious to hear your thoughts on it. {{{#!diff diff --git a/django/forms/models.py b/django/forms/models.py index 8084e16c8d..bbb4d94e33 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -370,10 +370,12 @@ def __init__( # if initial was provided, it should override the values from instance if initial is not None: object_data.update(initial) - # self._validate_unique will be set to True by BaseModelForm.clean(). - # It is False by default so overriding self.clean() and failing to call - # super will stop validate_unique from being called. + # self._validate_(unique|constraints) will be set to True by + # BaseModelForm.clean(). It is False by default so overriding + # self.clean() and failing to call super will stop + # validate_(unique|constraints) from being called. self._validate_unique = False + self._validate_constraints = False super().__init__( data, files, @@ -436,6 +438,7 @@ def _get_validation_exclusions(self): def clean(self): self._validate_unique = True + self._validate_constraints = True return self.cleaned_data def _update_errors(self, errors): @@ -495,13 +498,17 @@ def _post_clean(self): self._update_errors(e) try: - self.instance.full_clean(exclude=exclude, validate_unique=False) + self.instance.full_clean( + exclude=exclude, validate_unique=False, validate_constraints=False + ) except ValidationError as e: self._update_errors(e) - # Validate uniqueness if needed. + # Validate uniqueness and constraints if needed. if self._validate_unique: self.validate_unique() + if self._validate_constraints: + self.validate_constraints() def validate_unique(self): """ @@ -514,6 +521,17 @@ def validate_unique(self): except ValidationError as e: self._update_errors(e) + def validate_constraints(self): + """ + Call the instance's validate_constraints() method and update the form's + validation errors if any were raised. + """ + exclude = self._get_validation_exclusions() + try: + self.instance.validate_constraints(exclude=exclude) + except ValidationError as e: + self._update_errors(e) + def _save_m2m(self): """ Save the many-to-many fields and generic relations for this form. }}} -- Ticket URL: <https://code.djangoproject.com/ticket/35676#comment:1> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/010701914c7484d6-fe8fb74f-f5a9-46bd-9841-71910b95366e-000000%40eu-central-1.amazonses.com.