From 9208b4dd10cde4ec8792b132f5e298503a27ed30 Mon Sep 17 00:00:00 2001 From: David Vogt Date: Thu, 29 Nov 2018 10:02:20 +0100 Subject: [PATCH] Don't render write only relations (#522) --- AUTHORS | 1 + CHANGELOG.md | 1 + example/tests/unit/test_renderers.py | 32 +++++++++++++++++++++++++++- rest_framework_json_api/renderers.py | 4 ++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index f24fc6a6..25129f59 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,6 +3,7 @@ Adam Ziolkowski Alan Crosswell Anton Shutik Christian Zosel +David Vogt Greg Aker Jamie Bliss Jerel Unruh diff --git a/CHANGELOG.md b/CHANGELOG.md index a9d4e794..73a17c5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ any parts of the framework not mentioned in the documentation should generally b * Pass context from `PolymorphicModelSerializer` to child serializers to support fields which require a `request` context such as `url`. * Avoid patch on `RelationshipView` deleting relationship instance when constraint would allow null ([#242](https://github.com/django-json-api/django-rest-framework-json-api/issues/242)) * Avoid error with related urls when retrieving relationship which is referenced as `ForeignKey` on parent +* Do not render `write_only` relations ## [2.6.0] - 2018-09-20 diff --git a/example/tests/unit/test_renderers.py b/example/tests/unit/test_renderers.py index 42a45a94..8065e470 100644 --- a/example/tests/unit/test_renderers.py +++ b/example/tests/unit/test_renderers.py @@ -46,7 +46,7 @@ class ReadOnlyDummyTestViewSet(views.ReadOnlyModelViewSet): def render_dummy_test_serialized_view(view_class): - serializer = DummyTestSerializer(instance=Entry()) + serializer = view_class.serializer_class(instance=Entry()) renderer = JSONRenderer() return renderer.render( serializer.data, @@ -87,3 +87,33 @@ def test_render_format_keys(settings): result = json.loads(rendered.decode()) assert result['data']['attributes']['json-field'] == {'json-key': 'JsonValue'} + + +def test_writeonly_not_in_response(settings): + """Test that writeonly fields are not shown in list response""" + + settings.JSON_API_FORMAT_FIELD_NAMES = 'dasherize' + + class WriteonlyTestSerializer(serializers.ModelSerializer): + '''Serializer for testing the absence of write_only fields''' + comments = serializers.ResourceRelatedField( + many=True, + write_only=True, + queryset=Comment.objects.all() + ) + + rating = serializers.IntegerField(write_only=True) + + class Meta: + model = Entry + fields = ('comments', 'rating') + + class WriteOnlyDummyTestViewSet(views.ReadOnlyModelViewSet): + queryset = Entry.objects.all() + serializer_class = WriteonlyTestSerializer + + rendered = render_dummy_test_serialized_view(WriteOnlyDummyTestViewSet) + result = json.loads(rendered.decode()) + + assert 'rating' not in result['data']['attributes'] + assert 'relationships' not in result['data'] diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 8fae9483..de727f38 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -99,6 +99,10 @@ def extract_relationships(cls, fields, resource, resource_instance): if field_name == api_settings.URL_FIELD_NAME: continue + # don't output a key for write only fields + if fields[field_name].write_only: + continue + # Skip fields without relations if not isinstance( field, (relations.RelatedField, relations.ManyRelatedField, BaseSerializer)