Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite09a89a

Browse files
committed
chore: add comments and improve tests
1 parent8043317 commite09a89a

File tree

4 files changed

+47
-6
lines changed

4 files changed

+47
-6
lines changed

‎docs/api-guide/validators.md‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,28 @@ For example:
222222
extra_kwargs = {'client': {'required': False}}
223223
validators = [] # Remove a default "unique together" constraint.
224224

225+
###UniqueConstraint with conditions
226+
227+
When using Django's`UniqueConstraint` with conditions that reference other model fields, DRF will automatically use
228+
`UniqueTogetherValidator` instead of field-level`UniqueValidator`. This ensures proper validation behavior when the constraint
229+
effectively involves multiple fields.
230+
231+
For example, a single-field constraint with a condition becomes a multi-field validation when the condition references other fields.
232+
233+
class MyModel(models.Model):
234+
name = models.CharField(max_length=100)
235+
status = models.CharField(max_length=20)
236+
237+
class Meta:
238+
constraints = [
239+
models.UniqueConstraint(
240+
fields=['name'],
241+
condition=models.Q(status='active'),
242+
name='unique_active_name'
243+
)
244+
]
245+
246+
225247
##Updating nested serializers
226248

227249
When applying an update to an existing instance, uniqueness validators will

‎rest_framework/serializers.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,8 @@ def get_unique_together_constraints(self, model):
14511451
get_referenced_base_fields_from_q(constraint.condition)
14521452
)
14531453

1454+
# Combine constraint fields and condition fields. If the union
1455+
# involves multiple fields, treat as unique-together validation
14541456
required_fields= {*constraint.fields,*condition_fields}
14551457
iflen(required_fields)>1:
14561458
yield (

‎rest_framework/utils/field_mapping.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ def get_unique_validators(field_name, model_field):
8686
ifconditionisnotNone
8787
elseset()
8888
)
89+
# Only use UniqueValidator if the union of field and condition fields is 1
90+
# (i.e. no additional fields referenced in conditions)
8991
iflen(field_set|condition_fields)==1:
9092
yieldUniqueValidator(
9193
queryset=querysetifconditionisNoneelsequeryset.filter(condition),

‎tests/test_validators.py‎

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ def test_is_not_unique_together(self):
248248

249249
deftest_is_not_unique_together_condition_based(self):
250250
"""
251-
Failing unique together validation should result in nonfield errors when a condition-based
251+
Failing unique together validation should result in non-field errors when a condition-based
252252
unique together constraint is violated.
253253
"""
254254
ConditionUniquenessTogetherModel.objects.create(race_name='example',position=1)
@@ -275,10 +275,10 @@ def test_is_unique_together(self):
275275
'position':2
276276
}
277277

278-
deftest_unique_together_condition_based(self):
278+
deftest_is_unique_together_condition_based(self):
279279
"""
280-
In a unique together validation,one field may be non-unique
281-
so long astheset as a whole is unique.
280+
In acondition-basedunique together validation,data is valid when
281+
theconstrained field differs when the condition applies`.
282282
"""
283283
ConditionUniquenessTogetherModel.objects.create(race_name='example',position=1)
284284

@@ -290,6 +290,21 @@ def test_unique_together_condition_based(self):
290290
'position':1
291291
}
292292

293+
deftest_is_unique_together_when_condition_does_not_apply(self):
294+
"""
295+
In a condition-based unique together validation, data is valid when
296+
the condition does not apply, even if constrained fields match existing records.
297+
"""
298+
ConditionUniquenessTogetherModel.objects.create(race_name='example',position=1)
299+
300+
data= {'race_name':'example','position':2}
301+
serializer=ConditionUniquenessTogetherSerializer(data=data)
302+
assertserializer.is_valid()
303+
assertserializer.validated_data== {
304+
'race_name':'example',
305+
'position':2
306+
}
307+
293308
deftest_updated_instance_excluded_from_unique_together(self):
294309
"""
295310
When performing an update, the existing instance does not count
@@ -308,10 +323,10 @@ def test_updated_instance_excluded_from_unique_together_condition_based(self):
308323
When performing an update, the existing instance does not count
309324
as a match against uniqueness.
310325
"""
311-
ConditionUniquenessTogetherModel.objects.create(race_name='example',position=1)
326+
instance=ConditionUniquenessTogetherModel.objects.create(race_name='example',position=1)
312327

313328
data= {'race_name':'example','position':0}
314-
serializer=ConditionUniquenessTogetherSerializer(self.instance,data=data)
329+
serializer=ConditionUniquenessTogetherSerializer(instance,data=data)
315330
assertserializer.is_valid()
316331
assertserializer.validated_data== {
317332
'race_name':'example',

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp