Skip to content

Conversation

@nefrob
Copy link

Description

Resolves: #9707.

  • Apply unique together constraint validation to unique constraint with a single constraint field if there are other fields used in the constraint conditions

forunique_togetherinparent_class._meta.unique_together:
yieldunique_together, model._default_manager, [], None
forconstraintinparent_class._meta.constraints:
ifisinstance(constraint, models.UniqueConstraint)andlen(constraint.fields) >1:
Copy link
Collaborator

Choose a reason for hiding this comment

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

do this need to be removed?

Copy link
Author

Choose a reason for hiding this comment

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

We're now including the condition fields as part of the applicable fields that contribute to this count below. If we kept this here the condition fields would not be considered, which we need for this fix.

Choose a reason for hiding this comment

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

Shouldn't there be a distinction made between condition fields and constraint fields here?

Copy link
Author

@nefrobnefrobOct 16, 2025

Choose a reason for hiding this comment

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

We could split out the logic for clarity to require >1 constraint fields or 1 constraint field and 1+ condition fields distinct from the constraint field. Practically that would be the same however.

If you want to split out unique together constraints with a single constraint field and distinct condition fields into a new method, that would require a larger refactor of the existing constraint validation code.

@auvipyauvipy requested a review from CopilotOctober 16, 2025 07:29
@auvipyauvipy added this to the 3.17 milestone Oct 16, 2025
Copy link

CopilotAI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR updates DRF’s validation to correctly treat single-field UniqueConstraint entries with additional condition fields as unique-together validations rather than per-field UniqueValidators.

  • Extend unique-together detection to include UniqueConstraint with one field when the condition references other fields.
  • Adjust field-level UniqueValidator generation to only apply when no additional condition fields are referenced.
  • Add tests covering condition-based unique-together behavior.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

FileDescription
tests/test_validators.pyAdds a model, serializer, and tests for condition-based unique-together validation; updates expectations for single-field UniqueConstraint behavior.
rest_framework/utils/field_mapping.pyImports helper and changes logic to only create UniqueValidator when the union of fields and condition fields is a single field.
rest_framework/serializers.pyUpdates unique-together constraint discovery to include single-field UniqueConstraints when conditions reference additional fields.

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

elseset()
)
iflen(field_set|condition_fields) ==1:
yieldUniqueValidator(
Copy link
Contributor

Choose a reason for hiding this comment

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

Django’s UniqueConstraint supports custom error messages and codes via violation_error_message and violation_error_code, but as far as I can see these values are not propagated to UniqueValidator.
It would be great to have the same behaviour as for UniqueTogetherValidator, but I’m not sure this should be done within the scope of this PR.

Copy link
Author

Choose a reason for hiding this comment

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

Good point about custom error messages! That would be a nice enhancement but outside this PR's scope. Worth tracking in a separate issue.

@nefrobnefrobforce-pushed the nefrob/unique-constraint-with-condition-fields branch from 32c02c8 to e09a89aCompareDecember 12, 2025 18:23
@nefrobnefrob marked this pull request as ready for review December 12, 2025 18:32
@nefrob
Copy link
Author

Thanks for the feedback! Ready for re-review when you have a chance.

Copy link

CopilotAI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

deftest_is_unique_together_condition_based(self):
"""
In a condition-based unique together validation, data is valid when
the constrained field differs when the condition applies`.
Copy link

CopilotAIDec 13, 2025

Choose a reason for hiding this comment

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

There is a typo in the docstring. The backtick at the end of "when the condition applies" should be removed.

Suggested change
theconstrainedfielddifferswhentheconditionapplies`.
theconstrainedfielddifferswhentheconditionapplies.

Copilot uses AI. Check for mistakes.
Sign up for freeto 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.

Serializer UniqueConstraint validation fails incorrectly on create with conditional fields

4 participants

@nefrob@Adiorz@auvipy@s-aleshin