mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-27 08:29:59 +03:00
refactored validation of field names and created tests
This commit is contained in:
parent
07871b32d2
commit
54ca29dc58
|
@ -997,7 +997,7 @@ class ModelSerializer(Serializer):
|
||||||
# relationships as being a special case. During updates we already
|
# relationships as being a special case. During updates we already
|
||||||
# have an instance pk for the relationships to be associated with.
|
# have an instance pk for the relationships to be associated with.
|
||||||
m2m_fields = []
|
m2m_fields = []
|
||||||
partial_update_extra_fields = self.get_partial_update_extra_fields()
|
partial_update_extra_fields = self.get_partial_update_extra_fields(info.fields.keys())
|
||||||
update_fields = [*(partial_update_extra_fields or [])]
|
update_fields = [*(partial_update_extra_fields or [])]
|
||||||
for attr, value in validated_data.items():
|
for attr, value in validated_data.items():
|
||||||
if attr in info.relations and info.relations[attr].to_many:
|
if attr in info.relations and info.relations[attr].to_many:
|
||||||
|
@ -1633,7 +1633,7 @@ class ModelSerializer(Serializer):
|
||||||
|
|
||||||
return validators
|
return validators
|
||||||
|
|
||||||
def get_partial_update_extra_fields(self):
|
def get_partial_update_extra_fields(self, field_names):
|
||||||
partial_update_extra_fields = getattr(self.Meta, 'partial_update_extra_fields', None)
|
partial_update_extra_fields = getattr(self.Meta, 'partial_update_extra_fields', None)
|
||||||
|
|
||||||
if partial_update_extra_fields is not None and not isinstance(partial_update_extra_fields, (list, tuple)):
|
if partial_update_extra_fields is not None and not isinstance(partial_update_extra_fields, (list, tuple)):
|
||||||
|
@ -1642,10 +1642,9 @@ class ModelSerializer(Serializer):
|
||||||
type(partial_update_extra_fields).__name__
|
type(partial_update_extra_fields).__name__
|
||||||
)
|
)
|
||||||
|
|
||||||
fields = self.get_fields()
|
|
||||||
if partial_update_extra_fields is not None:
|
if partial_update_extra_fields is not None:
|
||||||
for field_name in partial_update_extra_fields:
|
for field_name in partial_update_extra_fields:
|
||||||
assert field_name in fields, (
|
assert field_name in field_names, (
|
||||||
"The field '{field_name}' was included on serializer "
|
"The field '{field_name}' was included on serializer "
|
||||||
"{serializer_class} in the 'partial_update_extra_fields' option, but does "
|
"{serializer_class} in the 'partial_update_extra_fields' option, but does "
|
||||||
"not match any model field.".format(
|
"not match any model field.".format(
|
||||||
|
|
|
@ -1301,6 +1301,11 @@ class Issue6751Model(models.Model):
|
||||||
char_field2 = models.CharField(max_length=100)
|
char_field2 = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
|
||||||
|
class Issue2648Model(models.Model):
|
||||||
|
char_field = models.CharField(max_length=100)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=Issue6751Model.many_to_many.through)
|
@receiver(m2m_changed, sender=Issue6751Model.many_to_many.through)
|
||||||
def process_issue6751model_m2m_changed(action, instance, **_):
|
def process_issue6751model_m2m_changed(action, instance, **_):
|
||||||
if action == 'post_add':
|
if action == 'post_add':
|
||||||
|
@ -1333,3 +1338,60 @@ class Issue6751Test(TestCase):
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
self.assertEqual(instance.char_field, 'value changed by signal')
|
self.assertEqual(instance.char_field, 'value changed by signal')
|
||||||
|
|
||||||
|
|
||||||
|
class Issue2648Test(TestCase):
|
||||||
|
def test_model_serializer_uses_partial_update_extra_fields_when_not_empty(self):
|
||||||
|
class TestSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Issue2648Model
|
||||||
|
partial_update_extra_fields = ('updated_at',)
|
||||||
|
fields = ('updated_at', 'char_field',)
|
||||||
|
|
||||||
|
instance = Issue2648Model.objects.create(char_field='initial value')
|
||||||
|
instance.updated_at = None
|
||||||
|
instance.save(update_fields=['updated_at'])
|
||||||
|
|
||||||
|
serializer = TestSerializer(instance=instance, data={'char_field': 'char_field updated value'}, partial=True)
|
||||||
|
serializer.is_valid()
|
||||||
|
serializer.save()
|
||||||
|
|
||||||
|
self.assertEqual(instance.char_field, 'char_field updated value')
|
||||||
|
self.assertIsNotNone(instance.updated_at)
|
||||||
|
|
||||||
|
def test_model_serializer_uses_partial_update_extra_fields_when_empty(self):
|
||||||
|
class TestSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Issue2648Model
|
||||||
|
partial_update_extra_fields = []
|
||||||
|
fields = ('updated_at', 'char_field',)
|
||||||
|
|
||||||
|
instance = Issue2648Model.objects.create(char_field='initial value')
|
||||||
|
instance.updated_at = None
|
||||||
|
instance.save(update_fields=['updated_at'])
|
||||||
|
|
||||||
|
serializer = TestSerializer(instance=instance, data={'char_field': 'char_field updated value'}, partial=True)
|
||||||
|
serializer.is_valid()
|
||||||
|
serializer.save()
|
||||||
|
|
||||||
|
self.assertEqual(instance.char_field, 'char_field updated value')
|
||||||
|
self.assertIsNone(instance.updated_at)
|
||||||
|
|
||||||
|
def test_model_serializer_validate_partial_update_extra_fields_are_model_fields(self):
|
||||||
|
class TestSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Issue2648Model
|
||||||
|
partial_update_extra_fields = ('missing_model_field',)
|
||||||
|
fields = ('updated_at', 'char_field',)
|
||||||
|
|
||||||
|
instance = Issue2648Model.objects.create(char_field='initial value')
|
||||||
|
serializer = TestSerializer(instance=instance, data={'char_field': 'char_field updated value'}, partial=True)
|
||||||
|
serializer.is_valid()
|
||||||
|
|
||||||
|
expected = (
|
||||||
|
"The field 'missing_model_field' was included on serializer "
|
||||||
|
"TestSerializer in the 'partial_update_extra_fields' option, but does "
|
||||||
|
"not match any model field."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(AssertionError, expected):
|
||||||
|
serializer.save()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user