From eaafc54ce26eb789e05d7369e997e07a1c3ec751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?George-Cristian=20B=C3=AErzan?= Date: Fri, 23 Feb 2018 15:53:42 +0200 Subject: [PATCH] #5848 Allow traversing nullable related fields --- rest_framework/relations.py | 2 +- tests/test_model_serializer.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/rest_framework/relations.py b/rest_framework/relations.py index c87b9299a..c4e364cf2 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -174,7 +174,7 @@ class RelatedField(Field): pass # Standard case, return the object instance. - return get_attribute(instance, self.source_attrs) + return super(RelatedField, self).get_attribute(instance) def get_choices(self, cutoff=None): queryset = self.get_queryset() diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index e55afe03e..e4fc8b37f 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -23,6 +23,8 @@ from django.utils import six from rest_framework import serializers from rest_framework.compat import postgres_fields, unicode_repr +from .models import NestedForeignKeySource + def dedent(blocktext): return '\n'.join([line[12:] for line in blocktext.splitlines()[1:-1]]) @@ -1164,6 +1166,25 @@ class Test5004UniqueChoiceField(TestCase): class TestFieldSource(TestCase): + def test_traverse_nullable_fk(self): + """ + A dotted source with nullable elements uses default when any item in the chain is None. #5849. + + Similar to model example from test_serializer.py `test_default_for_multiple_dotted_source` method, + but using RelatedField, rather than CharField. + """ + class TestSerializer(serializers.ModelSerializer): + target = serializers.PrimaryKeyRelatedField( + source='target.target', read_only=True, allow_null=True, default=None + ) + + class Meta: + model = NestedForeignKeySource + fields = ('target', ) + + model = NestedForeignKeySource.objects.create() + assert TestSerializer(model).data['target'] is None + def test_named_field_source(self): class TestSerializer(serializers.ModelSerializer):