Skip to content

Support violation_error_code and violation_error_message from UniqueConstraint in UniqueTogetherValidator #9766

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

s-aleshin
Copy link

Added support for retrieving custom violation_error_code (for django 5+) and violation_error_message from Django model-level UniqueConstraint definitions and passing them to UniqueTogetherValidator.

refs #9714 and #9352

The update ensures that:
• If violation_error_message or violation_error_code are explicitly defined on the model constraint, they are forwarded to the corresponding validator.
• If the constraint uses the default message/code, they are not passed, allowing the validator to use its own defaults.

Additionally, tests have been added to cover both scenarios:
• When a custom error message/code is used.
• When defaults are applied.

Note: The current structure of get_unique_together_constraints() may benefit from refactoring (e.g., returning a named structure for clarity and extensibility). This is outside the scope of this PR, but I may explore it in a future contribution.

"""
for parent_class in [model] + list(model._meta.parents):
for unique_together in parent_class._meta.unique_together:
yield unique_together, model._default_manager, [], None
yield unique_together, model._default_manager, [], None, None, None
Copy link
Collaborator

@peterthomassen peterthomassen Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change: Callers consuming the iterator will experience ValueError: too many values to unpack (expected 4).

For backwards compatibility, the old iterator structure should be returned, unless the new functionality is requested (such as via a default-False argument).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. I agree it was a critical change — I’ve restored the original signature and took a different approach.

@peterthomassen
Copy link
Collaborator

• If the constraint uses the default message/code, they are not passed, allowing the validator to use its own defaults.

What's the use case for that? (Why not use model-level default?)

…ture

Extracted error message logic to a separate method.

fix: conditionally include violation_error_code for Django >= 5.0

fix(validators): use custom error message and code from model constraints
@s-aleshin s-aleshin force-pushed the support-custom-error-unique-validator branch from 24e69af to c54c658 Compare August 18, 2025 14:41
@s-aleshin
Copy link
Author

• If the constraint uses the default message/code, they are not passed, allowing the validator to use its own defaults.

What's the use case for that? (Why not use model-level default?)

Returning the constraint’s default message would change the output and might break users relying on the validator’s default message—for example, in tests or UI rendering. I consider that the current behaviour should be maintained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants