Skip to content

Commit a11938c

Browse files
ryan-copperleafcarltongibson
authored andcommitted
Fixed instance being overwritten in pk-only optimization try/except block (#5747)
1 parent 7268643 commit a11938c

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

rest_framework/relations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ def get_attribute(self, instance):
163163
if self.use_pk_only_optimization() and self.source_attrs:
164164
# Optimized case, return a mock object only containing the pk attribute.
165165
try:
166-
instance = get_attribute(instance, self.source_attrs[:-1])
167-
value = instance.serializable_value(self.source_attrs[-1])
166+
attribute_instance = get_attribute(instance, self.source_attrs[:-1])
167+
value = attribute_instance.serializable_value(self.source_attrs[-1])
168168
if is_simple_callable(value):
169169
# Handle edge case where the relationship `source` argument
170170
# points to a `get_relationship()` method on the model

tests/test_relations.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44
from _pytest.monkeypatch import MonkeyPatch
55
from django.conf.urls import url
6-
from django.core.exceptions import ImproperlyConfigured
6+
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
77
from django.test import override_settings
88
from django.utils.datastructures import MultiValueDict
99

@@ -167,6 +167,22 @@ def test_representation_unsaved_object_with_non_nullable_pk(self):
167167
representation = self.field.to_representation(MockObject(pk=''))
168168
assert representation is None
169169

170+
def test_serialize_empty_relationship_attribute(self):
171+
class TestSerializer(serializers.Serializer):
172+
via_unreachable = serializers.HyperlinkedRelatedField(
173+
source='does_not_exist.unreachable',
174+
view_name='example',
175+
read_only=True,
176+
)
177+
178+
class TestSerializable:
179+
@property
180+
def does_not_exist(self):
181+
raise ObjectDoesNotExist
182+
183+
serializer = TestSerializer(TestSerializable())
184+
assert serializer.data == {'via_unreachable': None}
185+
170186
def test_hyperlinked_related_lookup_exists(self):
171187
instance = self.field.to_internal_value('http://example.org/example/foobar/')
172188
assert instance is self.queryset.items[0]

0 commit comments

Comments
 (0)