mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-29 17:39:48 +03:00
Fixed dotted write of non-relational fields, plus the related tests
This commit is contained in:
parent
bc5955f031
commit
2d52a0f180
|
@ -819,9 +819,21 @@ def raise_errors_on_nested_writes(method_name, serializer, validated_data, model
|
|||
# class UserSerializer(ModelSerializer):
|
||||
# ...
|
||||
# address = serializer.CharField('profile.address')
|
||||
#
|
||||
# Though, we can have a dotted field if it is not expressing a model relation.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# class NonRelationalPersonModel(models.Model):
|
||||
# profile = JSONField()
|
||||
#
|
||||
# class UserSerializer(ModelSerializer):
|
||||
# ...
|
||||
# address = serializer.CharField('profile.address')
|
||||
assert not any(
|
||||
len(field.source_attrs) > 1 and
|
||||
(field.source_attrs[0] in validated_data) and
|
||||
(field.source_attrs[0] in model_field_info.relations) and
|
||||
isinstance(validated_data[field.source_attrs[0]], (list, dict))
|
||||
for field in serializer._writable_fields
|
||||
), (
|
||||
|
|
|
@ -4,6 +4,9 @@ from django.http import QueryDict
|
|||
from django.test import TestCase
|
||||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.compat import postgres_fields
|
||||
from rest_framework.serializers import raise_errors_on_nested_writes
|
||||
from rest_framework.utils import model_meta
|
||||
|
||||
|
||||
class TestNestedSerializer:
|
||||
|
@ -302,3 +305,55 @@ class TestNestedWriteErrors(TestCase):
|
|||
'serializer `tests.test_serializer_nested.DottedAddressSerializer`, '
|
||||
'or set `read_only=True` on dotted-source serializer fields.'
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif('not postgres_fields')
|
||||
class TestNestedNonRelationalFieldWrite:
|
||||
"""
|
||||
Test that raise_errors_on_nested_writes does not raise `AssertionError` when the
|
||||
model field is not a relation.
|
||||
"""
|
||||
|
||||
def test_nested_serializer_create_and_update(self):
|
||||
class NonRelationalPersonModel(models.Model):
|
||||
"""Model declaring a postgres JSONField"""
|
||||
data = postgres_fields.JSONField()
|
||||
|
||||
class NonRelationalPersonDataSerializer(serializers.Serializer):
|
||||
occupation = serializers.CharField()
|
||||
|
||||
class NonRelationalPersonSerializer(serializers.ModelSerializer):
|
||||
data = NonRelationalPersonDataSerializer()
|
||||
|
||||
class Meta:
|
||||
model = NonRelationalPersonModel
|
||||
fields = ['data']
|
||||
|
||||
serializer = NonRelationalPersonSerializer(data={'data': {'occupation': 'developer'}})
|
||||
assert serializer.is_valid()
|
||||
assert serializer.validated_data == {'data': {'occupation': 'developer'}}
|
||||
ModelClass = serializer.Meta.model
|
||||
info = model_meta.get_field_info(ModelClass)
|
||||
raise_errors_on_nested_writes('create', serializer, serializer.validated_data, info)
|
||||
raise_errors_on_nested_writes('update', serializer, serializer.validated_data, info)
|
||||
|
||||
def test_dotted_source_field_create_and_update(self):
|
||||
class NonRelationalPersonModel(models.Model):
|
||||
"""Model declaring a postgres JSONField"""
|
||||
data = postgres_fields.JSONField()
|
||||
|
||||
class DottedNonRelationalPersonSerializer(serializers.ModelSerializer):
|
||||
occupation = serializers.CharField(source='data.occupation')
|
||||
|
||||
class Meta:
|
||||
model = NonRelationalPersonModel
|
||||
fields = ['occupation']
|
||||
|
||||
serializer = DottedNonRelationalPersonSerializer(data={'occupation': 'developer'})
|
||||
assert serializer.is_valid()
|
||||
assert serializer.validated_data == {'data': {'occupation': 'developer'}}
|
||||
ModelClass = serializer.Meta.model
|
||||
info = model_meta.get_field_info(ModelClass)
|
||||
raise_errors_on_nested_writes('create', serializer, serializer.validated_data, info)
|
||||
raise_errors_on_nested_writes('update', serializer, serializer.validated_data, info)
|
||||
assert serializer.data == {'occupation': 'developer'}
|
||||
|
|
Loading…
Reference in New Issue
Block a user