Skip to content

Commit 0e44af2

Browse files
committed
Ensure DynamicRelationField.to_representation is passed correct instance
1 parent cacad3c commit 0e44af2

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

dynamic_rest/fields/fields.py

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -268,20 +268,7 @@ def _is_dynamic(self):
268268
)
269269

270270
def get_attribute(self, instance):
271-
serializer = self.serializer
272-
model = serializer.get_model()
273-
274-
# attempt to optimize by reading the related ID directly
275-
# from the current instance rather than from the related object
276-
if not self.kwargs['many'] and serializer.id_only():
277-
return instance
278-
elif model is not None:
279-
try:
280-
return getattr(instance, self.source)
281-
except model.DoesNotExist:
282-
return None
283-
else:
284-
return instance
271+
return instance
285272

286273
def to_representation(self, instance):
287274
"""Represent the relationship, either as an ID or object."""
@@ -296,18 +283,18 @@ def to_representation(self, instance):
296283
# try the faster way first:
297284
if hasattr(instance, source_id):
298285
return getattr(instance, source_id)
299-
elif model is not None:
300-
# this is probably a one-to-one field, or a reverse related
301-
# lookup, so let's look it up the slow way and let the
302-
# serializer handle the id dereferencing
303-
try:
304-
instance = getattr(instance, source)
305-
except model.DoesNotExist:
306-
instance = None
307286

308287
# dereference ephemeral objects
309288
if model is None:
310289
instance = getattr(instance, source)
290+
else:
291+
# this is probably a one-to-one field, or a reverse related
292+
# lookup, so let's look it up the slow way and let the
293+
# serializer handle the id dereferencing
294+
try:
295+
instance = getattr(instance, source)
296+
except model.DoesNotExist:
297+
instance = None
311298

312299
if instance is None:
313300
return None

tests/test_serializers.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import unittest
2-
from mock import patch
2+
from mock import patch, Mock
33
from collections import OrderedDict
44

55
from django.test import TestCase, override_settings
@@ -523,6 +523,30 @@ def test_post_processor(data):
523523
data = serializer.data
524524
self.assertTrue(data.get('post_processed'))
525525

526+
def test_to_representation_passed_model_instance(self):
527+
mock_obj = Mock()
528+
529+
class GroupRelationField(DynamicRelationField):
530+
def to_representation(self, instance):
531+
mock_obj(instance)
532+
# Dead men have no groups
533+
if instance.is_dead:
534+
return []
535+
return super(GroupRelationField, self).to_representation(instance)
536+
537+
class UserCustomGroupFieldSerializer(UserSerializer):
538+
groups = GroupRelationField(GroupSerializer, many=True, embed=True)
539+
540+
user = User.objects.create(name='Dead', last_name='Mort', is_dead=True)
541+
user.groups.add(*self.fixture.groups)
542+
543+
data = UserCustomGroupFieldSerializer(
544+
user, request_fields={'groups': {'name': True}}
545+
).data
546+
547+
assert data['groups'] == []
548+
mock_obj.assert_called_once_with(user)
549+
526550

527551
class TestListSerializer(TestCase):
528552

0 commit comments

Comments
 (0)