55from collections import OrderedDict
66
77import inflection
8- from django .db .models import Manager , QuerySet
8+ from django .db .models import Manager
99from django .utils import six , encoding
1010from rest_framework import relations
1111from rest_framework import renderers
@@ -111,8 +111,10 @@ def get_pk(obj):
111111 if relation_instance is not None else list ()
112112
113113 for related_object in relation_queryset :
114- relation_data .append (
115- OrderedDict ([('type' , relation_type ), ('id' , encoding .force_text (get_pk (related_object )))])
114+ relation_data .append (OrderedDict ([
115+ ('type' , relation_type ),
116+ ('id' , encoding .force_text (getattr (
117+ related_object , field .lookup_field )))])
116118 )
117119
118120 data .update ({field_name : {
@@ -144,12 +146,18 @@ def get_pk(obj):
144146 continue
145147
146148 if isinstance (field , (relations .PrimaryKeyRelatedField , relations .HyperlinkedRelatedField )):
147- resolved , relation = utils .get_relation_instance (resource_instance , '%s_id' % source , field .parent )
148- if not resolved :
149- continue
150- relation_id = get_pk (
151- getattr (resource_instance , source )
152- ) if resource .get (field_name ) else None
149+ lookup_field = getattr (field , 'lookup_field' , None )
150+ if lookup_field :
151+ relation_id = getattr (
152+ getattr (resource_instance , source ), lookup_field )
153+ else :
154+ resolved , relation = utils .get_relation_instance (
155+ resource_instance , source , field .parent )
156+ if not resolved :
157+ continue
158+ relation_id = get_pk (
159+ getattr (resource_instance , source )
160+ ) if resource .get (field_name ) else None
153161 relation_data = {
154162 'data' : (
155163 OrderedDict ([('type' , relation_type ), ('id' , encoding .force_text (relation_id ))])
@@ -198,7 +206,9 @@ def get_pk(obj):
198206
199207 relation_data .append (OrderedDict ([
200208 ('type' , nested_resource_instance_type ),
201- ('id' , encoding .force_text (get_pk (nested_resource_instance )))
209+ ('id' , encoding .force_text (getattr (
210+ nested_resource_instance ,
211+ field .child_relation .lookup_field )))
202212 ]))
203213 data .update ({
204214 field_name : {
@@ -228,7 +238,9 @@ def get_pk(obj):
228238 utils .get_resource_type_from_instance (nested_resource_instance )
229239 )
230240
231- instance_pk_name = nested_resource_instance ._meta .pk .name
241+ instance_pk_name = (
242+ getattr (field , 'lookup_field' , None ) or
243+ nested_resource_instance ._meta .pk .name )
232244 if instance_pk_name in nested_resource_data :
233245 pk = nested_resource_data [instance_pk_name ]
234246 else :
@@ -247,12 +259,19 @@ def get_pk(obj):
247259 if not resolved :
248260 continue
249261
262+ url_field_name = getattr (field , 'url_field_name' , 'url' )
263+ if url_field_name in field .fields :
264+ id_ = getattr (
265+ relation_instance ,
266+ field [url_field_name ].lookup_field )
267+ else :
268+ id_ = get_pk (relation_instance )
250269 data .update ({
251270 field_name : {
252271 'data' : (
253272 OrderedDict ([
254273 ('type' , relation_type ),
255- ('id' , get_pk ( relation_instance ))
274+ ('id' , encoding . force_text ( id_ ))
256275 ]) if resource .get (field_name ) else None )
257276 }
258277 })
@@ -402,6 +421,12 @@ def extract_root_meta(cls, serializer, resource):
402421 def build_json_resource_obj (cls , fields , resource , resource_instance , resource_name ):
403422 if resource_instance is None :
404423 pk = None
424+ elif 'url' in fields :
425+ pk = getattr (resource_instance , fields ['url' ].lookup_field )
426+ pk = encoding .force_text (pk )
427+ elif 'id' in fields :
428+ pk = fields ['id' ].get_attribute (resource_instance )
429+ pk = encoding .force_text (pk )
405430 else :
406431 # Check if the primary key exists in the resource by getting the primary keys attribute name.
407432 pk_attr = resource_instance ._meta .pk .name
0 commit comments