33from rest_framework .fields import MISSING_ERROR_MESSAGE
44from rest_framework .relations import *
55from django .utils .translation import ugettext_lazy as _
6+ from django .db .models .query import QuerySet
67
78from rest_framework_json_api .exceptions import Conflict
89from rest_framework_json_api .utils import Hyperlink , \
910 get_resource_type_from_queryset , get_resource_type_from_instance , \
1011 get_included_serializers , get_resource_type_from_serializer
1112
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-
3413
3514class ResourceRelatedField (PrimaryKeyRelatedField ):
3615 self_link_view_name = None
@@ -47,21 +26,6 @@ class ResourceRelatedField(PrimaryKeyRelatedField):
4726 'no_match' : _ ('Invalid hyperlink - No URL match.' ),
4827 }
4928
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-
6529 def __init__ (self , self_link_view_name = None , related_link_view_name = None , ** kwargs ):
6630 if self_link_view_name is not None :
6731 self .self_link_view_name = self_link_view_name
@@ -205,11 +169,48 @@ def choices(self):
205169 ])
206170
207171
172+
208173class SerializerMethodResourceRelatedField (ResourceRelatedField ):
174+ """
175+ Allows us to use serializer method RelatedFields
176+ with return querysets
177+ """
178+ def __new__ (cls , * args , ** kwargs ):
179+ """
180+ We override this because getting serializer methods
181+ fails at the base class when many=True
182+ """
183+ if kwargs .pop ('many' , False ):
184+ return cls .many_init (* args , ** kwargs )
185+ return super (ResourceRelatedField , cls ).__new__ (cls , * args , ** kwargs )
186+
187+ def __init__ (self , child_relation = None , * args , ** kwargs ):
188+ model = kwargs .pop ('model' , None )
189+ if model :
190+ self .model = model
191+ super (SerializerMethodResourceRelatedField , self ).__init__ (child_relation , * args , ** kwargs )
192+
193+ @classmethod
194+ def many_init (cls , * args , ** kwargs ):
195+ list_kwargs = {'child_relation' : cls (* args , ** kwargs )}
196+ for key in kwargs .keys ():
197+ if key in ('model' ,) + MANY_RELATION_KWARGS :
198+ list_kwargs [key ] = kwargs [key ]
199+ return SerializerMethodResourceRelatedField (** list_kwargs )
200+
209201 def get_attribute (self , instance ):
210202 # check for a source fn defined on the serializer instead of the model
211203 if self .source and hasattr (self .parent , self .source ):
212204 serializer_method = getattr (self .parent , self .source )
213205 if hasattr (serializer_method , '__call__' ):
214206 return serializer_method (instance )
215- return super (ResourceRelatedField , self ).get_attribute (instance )
207+ return super (SerializerMethodResourceRelatedField , self ).get_attribute (instance )
208+
209+ def to_representation (self , value ):
210+ if isinstance (value , QuerySet ):
211+ base = super (SerializerMethodResourceRelatedField , self )
212+ return [base .to_representation (x ) for x in value ]
213+ return super (SerializerMethodResourceRelatedField , self ).to_representation (value )
214+
215+ def get_links (self , obj = None , lookup_field = 'pk' ):
216+ return OrderedDict ()
0 commit comments