mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
Fix dotted-source field checking on serializer write (#6786)
* Add tests for raise_errors_on_nested_writes * Fix dotted-source field checking on serializer write The code was previously checking the validated data for the field's attribute name, however, the data contain the first source attr.
This commit is contained in:
parent
372f4fde20
commit
bd6a1b3b6c
|
@ -819,10 +819,10 @@ def raise_errors_on_nested_writes(method_name, serializer, validated_data):
|
|||
# ...
|
||||
# address = serializer.CharField('profile.address')
|
||||
assert not any(
|
||||
'.' in field.source and
|
||||
(key in validated_data) and
|
||||
isinstance(validated_data[key], (list, dict))
|
||||
for key, field in serializer.fields.items()
|
||||
len(field.source_attrs) > 1 and
|
||||
(field.source_attrs[0] in validated_data) and
|
||||
isinstance(validated_data[field.source_attrs[0]], (list, dict))
|
||||
for field in serializer._writable_fields
|
||||
), (
|
||||
'The `.{method_name}()` method does not support writable dotted-source '
|
||||
'fields by default.\nWrite an explicit `.{method_name}()` method for '
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import pytest
|
||||
from django.db import models
|
||||
from django.http import QueryDict
|
||||
from django.test import TestCase
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
|
@ -241,3 +244,61 @@ class TestNotRequiredNestedSerializerWithMany:
|
|||
serializer = self.Serializer(data=input_data)
|
||||
assert serializer.is_valid()
|
||||
assert 'nested' in serializer.validated_data
|
||||
|
||||
|
||||
class NestedWriteProfile(models.Model):
|
||||
address = models.CharField(max_length=100)
|
||||
|
||||
|
||||
class NestedWritePerson(models.Model):
|
||||
profile = models.ForeignKey(NestedWriteProfile, on_delete=models.CASCADE)
|
||||
|
||||
|
||||
class TestNestedWriteErrors(TestCase):
|
||||
# tests for rests_framework.serializers.raise_errors_on_nested_writes
|
||||
def test_nested_serializer_error(self):
|
||||
class ProfileSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = NestedWriteProfile
|
||||
fields = ['address']
|
||||
|
||||
class NestedProfileSerializer(serializers.ModelSerializer):
|
||||
profile = ProfileSerializer()
|
||||
|
||||
class Meta:
|
||||
model = NestedWritePerson
|
||||
fields = ['profile']
|
||||
|
||||
serializer = NestedProfileSerializer(data={'profile': {'address': '52 festive road'}})
|
||||
assert serializer.is_valid()
|
||||
assert serializer.validated_data == {'profile': {'address': '52 festive road'}}
|
||||
with pytest.raises(AssertionError) as exc_info:
|
||||
serializer.save()
|
||||
|
||||
assert str(exc_info.value) == (
|
||||
'The `.create()` method does not support writable nested fields by '
|
||||
'default.\nWrite an explicit `.create()` method for serializer '
|
||||
'`tests.test_serializer_nested.NestedProfileSerializer`, or set '
|
||||
'`read_only=True` on nested serializer fields.'
|
||||
)
|
||||
|
||||
def test_dotted_source_field_error(self):
|
||||
class DottedAddressSerializer(serializers.ModelSerializer):
|
||||
address = serializers.CharField(source='profile.address')
|
||||
|
||||
class Meta:
|
||||
model = NestedWritePerson
|
||||
fields = ['address']
|
||||
|
||||
serializer = DottedAddressSerializer(data={'address': '52 festive road'})
|
||||
assert serializer.is_valid()
|
||||
assert serializer.validated_data == {'profile': {'address': '52 festive road'}}
|
||||
with pytest.raises(AssertionError) as exc_info:
|
||||
serializer.save()
|
||||
|
||||
assert str(exc_info.value) == (
|
||||
'The `.create()` method does not support writable dotted-source '
|
||||
'fields by default.\nWrite an explicit `.create()` method for '
|
||||
'serializer `tests.test_serializer_nested.DottedAddressSerializer`, '
|
||||
'or set `read_only=True` on dotted-source serializer fields.'
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user