Fixed instance being overwritten in pk-only optimization try/except block (#5747)

This commit is contained in:
Ryan O’Hara 2018-04-24 07:15:38 -07:00 committed by Carlton Gibson
parent 7268643b25
commit a11938ce96
2 changed files with 19 additions and 3 deletions

View File

@ -163,8 +163,8 @@ class RelatedField(Field):
if self.use_pk_only_optimization() and self.source_attrs: if self.use_pk_only_optimization() and self.source_attrs:
# Optimized case, return a mock object only containing the pk attribute. # Optimized case, return a mock object only containing the pk attribute.
try: try:
instance = get_attribute(instance, self.source_attrs[:-1]) attribute_instance = get_attribute(instance, self.source_attrs[:-1])
value = instance.serializable_value(self.source_attrs[-1]) value = attribute_instance.serializable_value(self.source_attrs[-1])
if is_simple_callable(value): if is_simple_callable(value):
# Handle edge case where the relationship `source` argument # Handle edge case where the relationship `source` argument
# points to a `get_relationship()` method on the model # points to a `get_relationship()` method on the model

View File

@ -3,7 +3,7 @@ import uuid
import pytest import pytest
from _pytest.monkeypatch import MonkeyPatch from _pytest.monkeypatch import MonkeyPatch
from django.conf.urls import url from django.conf.urls import url
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
from django.test import override_settings from django.test import override_settings
from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MultiValueDict
@ -167,6 +167,22 @@ class TestHyperlinkedRelatedField(APISimpleTestCase):
representation = self.field.to_representation(MockObject(pk='')) representation = self.field.to_representation(MockObject(pk=''))
assert representation is None assert representation is None
def test_serialize_empty_relationship_attribute(self):
class TestSerializer(serializers.Serializer):
via_unreachable = serializers.HyperlinkedRelatedField(
source='does_not_exist.unreachable',
view_name='example',
read_only=True,
)
class TestSerializable:
@property
def does_not_exist(self):
raise ObjectDoesNotExist
serializer = TestSerializer(TestSerializable())
assert serializer.data == {'via_unreachable': None}
def test_hyperlinked_related_lookup_exists(self): def test_hyperlinked_related_lookup_exists(self):
instance = self.field.to_internal_value('http://example.org/example/foobar/') instance = self.field.to_internal_value('http://example.org/example/foobar/')
assert instance is self.queryset.items[0] assert instance is self.queryset.items[0]