From 3801ef7c6bc50acffc71d876e00530192cdae645 Mon Sep 17 00:00:00 2001 From: Konstantinos Tselepakis Date: Fri, 6 Sep 2019 08:36:20 +0300 Subject: [PATCH] Minor fixes * no need to change `raise_errors_on_nested_writes` signature * declare nested-model outside of the test class --- rest_framework/serializers.py | 12 ++++++------ tests/test_serializer_nested.py | 28 +++++++++++----------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 67b29d53a..a45f2b7d8 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -773,7 +773,7 @@ class ListSerializer(BaseSerializer): # ModelSerializer & HyperlinkedModelSerializer # -------------------------------------------- -def raise_errors_on_nested_writes(method_name, serializer, validated_data, model_field_info): +def raise_errors_on_nested_writes(method_name, serializer, validated_data): """ Give explicit errors when users attempt to pass writable nested data. @@ -791,6 +791,8 @@ def raise_errors_on_nested_writes(method_name, serializer, validated_data, model * Silently ignore the nested part of the update. * Automatically create a profile instance. """ + ModelClass = serializer.Meta.model + model_field_info = model_meta.get_field_info(ModelClass) # Ensure we don't have a writable nested field. For example: # @@ -820,9 +822,7 @@ def raise_errors_on_nested_writes(method_name, serializer, validated_data, model # ... # address = serializer.CharField('profile.address') # - # Though, we can have a dotted field if it is not expressing a model relation. - # - # For example: + # Though, non-relational fields (e.g., JSONField) are acceptable. For example: # # class NonRelationalPersonModel(models.Model): # profile = JSONField() @@ -931,7 +931,7 @@ class ModelSerializer(Serializer): ModelClass = self.Meta.model info = model_meta.get_field_info(ModelClass) - raise_errors_on_nested_writes('create', self, validated_data, info) + raise_errors_on_nested_writes('create', self, validated_data) # Remove many-to-many relationships from validated_data. # They are not valid arguments to the default `.create()` method, @@ -973,7 +973,7 @@ class ModelSerializer(Serializer): def update(self, instance, validated_data): info = model_meta.get_field_info(instance) - raise_errors_on_nested_writes('update', self, validated_data, info) + raise_errors_on_nested_writes('update', self, validated_data) # Simply set each attribute on the instance, and then save it. # Note that unlike `.create()` we don't need to treat many-to-many diff --git a/tests/test_serializer_nested.py b/tests/test_serializer_nested.py index 92f2084df..a614e05d1 100644 --- a/tests/test_serializer_nested.py +++ b/tests/test_serializer_nested.py @@ -6,7 +6,6 @@ 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: @@ -307,7 +306,13 @@ class TestNestedWriteErrors(TestCase): ) -@pytest.mark.skipif('not postgres_fields') +if postgres_fields: + class NonRelationalPersonModel(models.Model): + """Model declaring a postgres JSONField""" + data = postgres_fields.JSONField() + + +@pytest.mark.skipif(not postgres_fields, reason='psycopg2 is not installed') class TestNestedNonRelationalFieldWrite: """ Test that raise_errors_on_nested_writes does not raise `AssertionError` when the @@ -315,9 +320,6 @@ class TestNestedNonRelationalFieldWrite: """ 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() @@ -332,15 +334,10 @@ class TestNestedNonRelationalFieldWrite: 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) + raise_errors_on_nested_writes('create', serializer, serializer.validated_data) + raise_errors_on_nested_writes('update', serializer, serializer.validated_data) 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') @@ -352,8 +349,5 @@ class TestNestedNonRelationalFieldWrite: 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'} + raise_errors_on_nested_writes('create', serializer, serializer.validated_data) + raise_errors_on_nested_writes('update', serializer, serializer.validated_data)