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
|
||||
# have an instance pk for the relationships to be associated with.
|
||||
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 [])]
|
||||
for attr, value in validated_data.items():
|
||||
if attr in info.relations and info.relations[attr].to_many:
|
||||
|
@ -1633,7 +1633,7 @@ class ModelSerializer(Serializer):
|
|||
|
||||
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)
|
||||
|
||||
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__
|
||||
)
|
||||
|
||||
fields = self.get_fields()
|
||||
if partial_update_extra_fields is not None:
|
||||
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 "
|
||||
"{serializer_class} in the 'partial_update_extra_fields' option, but does "
|
||||
"not match any model field.".format(
|
||||
|
|
|
@ -1301,6 +1301,11 @@ class Issue6751Model(models.Model):
|
|||
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)
|
||||
def process_issue6751model_m2m_changed(action, instance, **_):
|
||||
if action == 'post_add':
|
||||
|
@ -1333,3 +1338,60 @@ class Issue6751Test(TestCase):
|
|||
serializer.save()
|
||||
|
||||
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