From 5d40e761f3c903a0456893994ee52faaa6e52dc3 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Fri, 16 Mar 2018 14:23:48 +0100 Subject: [PATCH] Test using model objects for dotted source default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … when path components may be null. Ref #5375, #5727 --- tests/models.py | 11 +++++++++++ tests/test_serializer.py | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/tests/models.py b/tests/models.py index e5d49a0a5..6aeceb934 100644 --- a/tests/models.py +++ b/tests/models.py @@ -69,6 +69,17 @@ class NullableUUIDForeignKeySource(RESTFrameworkModel): on_delete=models.CASCADE) +class NestedForeignKeySource(RESTFrameworkModel): + """ + Used for testing FK chain. A -> B -> C. + """ + name = models.CharField(max_length=100) + target = models.ForeignKey(NullableForeignKeySource, null=True, blank=True, + related_name='nested_sources', + verbose_name='Intermediate target object', + on_delete=models.CASCADE) + + # OneToOne class OneToOneTarget(RESTFrameworkModel): name = models.CharField(max_length=100) diff --git a/tests/test_serializer.py b/tests/test_serializer.py index da1394515..120632572 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -14,6 +14,9 @@ from rest_framework import fields, relations, serializers from rest_framework.compat import unicode_repr from rest_framework.fields import Field +from .models import ( + ForeignKeyTarget, NestedForeignKeySource, NullableForeignKeySource +) from .utils import MockObject try: @@ -453,6 +456,22 @@ class TestDefaultOutput: assert Serializer({'a': {'b': {'c': 'abc'}}}).data == {'c': 'abc'} + # Same test using model objects to exercise both paths in + # rest_framework.fields.get_attribute() (#5880) + class ModelSerializer(serializers.Serializer): + target = serializers.CharField(default='x', source='target.target.name') + + a = NestedForeignKeySource(name="Root Object", target=None) + assert ModelSerializer(a).data == {'target': 'x'} + + b = NullableForeignKeySource(name="Intermediary Object", target=None) + a.target = b + assert ModelSerializer(a).data == {'target': 'x'} + + c = ForeignKeyTarget(name="Target Object") + b.target = c + assert ModelSerializer(a).data == {'target': 'Target Object'} + def test_default_for_nested_serializer(self): class NestedSerializer(serializers.Serializer): a = serializers.CharField(default='1')