11import json
22
33from rest_framework .fields import MISSING_ERROR_MESSAGE
4+ from rest_framework .serializers import ListSerializer
45from rest_framework .relations import *
56from django .utils .translation import ugettext_lazy as _
7+ from django .db .models .query import QuerySet
68
79from rest_framework_json_api .exceptions import Conflict
810from rest_framework_json_api .utils import Hyperlink , \
911 get_resource_type_from_queryset , get_resource_type_from_instance , \
1012 get_included_serializers , get_resource_type_from_serializer
1113
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-
3414
3515class ResourceRelatedField (PrimaryKeyRelatedField ):
3616 self_link_view_name = None
@@ -47,21 +27,6 @@ class ResourceRelatedField(PrimaryKeyRelatedField):
4727 'no_match' : _ ('Invalid hyperlink - No URL match.' ),
4828 }
4929
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-
6530 def __init__ (self , self_link_view_name = None , related_link_view_name = None , ** kwargs ):
6631 if self_link_view_name is not None :
6732 self .self_link_view_name = self_link_view_name
@@ -205,11 +170,48 @@ def choices(self):
205170 ])
206171
207172
173+
208174class SerializerMethodResourceRelatedField (ResourceRelatedField ):
175+ """
176+ Allows us to use serializer method RelatedFields
177+ with return querysets
178+ """
179+ def __new__ (cls , * args , ** kwargs ):
180+ """
181+ We override this because getting serializer methods
182+ fails at the base class when many=True
183+ """
184+ if kwargs .pop ('many' , False ):
185+ return cls .many_init (* args , ** kwargs )
186+ return super (ResourceRelatedField , cls ).__new__ (cls , * args , ** kwargs )
187+
188+ def __init__ (self , child_relation = None , * args , ** kwargs ):
189+ model = kwargs .pop ('model' , None )
190+ if model :
191+ self .model = model
192+ super (SerializerMethodResourceRelatedField , self ).__init__ (child_relation , * args , ** kwargs )
193+
194+ @classmethod
195+ def many_init (cls , * args , ** kwargs ):
196+ list_kwargs = {'child_relation' : cls (* args , ** kwargs )}
197+ for key in kwargs .keys ():
198+ if key in ('model' ,) + MANY_RELATION_KWARGS :
199+ list_kwargs [key ] = kwargs [key ]
200+ return SerializerMethodResourceRelatedField (** list_kwargs )
201+
209202 def get_attribute (self , instance ):
210203 # check for a source fn defined on the serializer instead of the model
211204 if self .source and hasattr (self .parent , self .source ):
212205 serializer_method = getattr (self .parent , self .source )
213206 if hasattr (serializer_method , '__call__' ):
214207 return serializer_method (instance )
215- return super (ResourceRelatedField , self ).get_attribute (instance )
208+ return super (SerializerMethodResourceRelatedField , self ).get_attribute (instance )
209+
210+ def to_representation (self , value ):
211+ if isinstance (value , QuerySet ):
212+ base = super (SerializerMethodResourceRelatedField , self )
213+ return [base .to_representation (x ) for x in value ]
214+ return super (SerializerMethodResourceRelatedField , self ).to_representation (value )
215+
216+ def get_links (self , obj = None , lookup_field = 'pk' ):
217+ return OrderedDict ()
0 commit comments