Skip to content

Commit 63a2b36

Browse files
sonthonaxrkjerel
authored andcommitted
ResourceRelatedField now accepts serializer methods when many=True
1 parent e4594e0 commit 63a2b36

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

‎rest_framework_json_api/relations.py

+37
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,28 @@
99
get_resource_type_from_queryset, get_resource_type_from_instance, \
1010
get_included_serializers, get_resource_type_from_serializer
1111

12+
import pdb
13+
14+
JSONAPI_MANY_RELATION_KWARGS = ('model', ) + MANY_RELATION_KWARGS
15+
16+
class ManyResourceRelatedField(ManyRelatedField):
17+
"""
18+
Allows us to use serializer method RelatedFields
19+
with return querysets
20+
"""
21+
def __init__(self, child_relation=None, *args, **kwargs):
22+
model = kwargs.pop('model', None)
23+
if model:
24+
self.model = model
25+
super(ManyResourceRelatedField, self).__init__(child_relation, *args, **kwargs)
26+
27+
def get_attribute(self, instance):
28+
if self.source and hasattr(self.parent, self.source):
29+
serializer_method = getattr(self.parent, self.source)
30+
if hasattr(serializer_method, '__call__'):
31+
return serializer_method(instance)
32+
return super(ManyResourceRelatedField, self).get_attribute(instance)
33+
1234

1335
class ResourceRelatedField(PrimaryKeyRelatedField):
1436
self_link_view_name = None
@@ -25,6 +47,21 @@ class ResourceRelatedField(PrimaryKeyRelatedField):
2547
'no_match': _('Invalid hyperlink - No URL match.'),
2648
}
2749

50+
def __new__(cls, *args, **kwargs):
51+
# We override this because getting
52+
# serializer methods fails when many is true
53+
if kwargs.pop('many', False):
54+
return cls.many_init(*args, **kwargs)
55+
return super(ResourceRelatedField, cls).__new__(cls, *args, **kwargs)
56+
57+
@classmethod
58+
def many_init(cls, *args, **kwargs):
59+
list_kwargs = {'child_relation': cls(*args, **kwargs)}
60+
for key in kwargs.keys():
61+
if key in JSONAPI_MANY_RELATION_KWARGS:
62+
list_kwargs[key] = kwargs[key]
63+
return ManyResourceRelatedField(**list_kwargs)
64+
2865
def __init__(self, self_link_view_name=None, related_link_view_name=None, **kwargs):
2966
if self_link_view_name is not None:
3067
self.self_link_view_name = self_link_view_name

0 commit comments

Comments
 (0)