@@ -90,6 +90,15 @@ def extract_relationships(cls, fields, resource, resource_instance):
90
90
source = field .source
91
91
relation_type = utils .get_related_resource_type (field )
92
92
93
+ # Take a model and return it's primary key, calling the primary key fields 'get_attribute'
94
+ # function or the models .pk property.
95
+ def get_pk (obj ):
96
+ pk_attr = obj ._meta .pk .name
97
+ if hasattr (field , 'fields' ) and pk_attr in field .fields :
98
+ return field .fields [pk_attr ].get_attribute (obj )
99
+ else :
100
+ return obj .pk
101
+
93
102
if isinstance (field , relations .HyperlinkedIdentityField ):
94
103
resolved , relation_instance = utils .get_relation_instance (resource_instance , source , field .parent )
95
104
if not resolved :
@@ -103,7 +112,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
103
112
104
113
for related_object in relation_queryset :
105
114
relation_data .append (
106
- OrderedDict ([('type' , relation_type ), ('id' , encoding .force_text (related_object . pk ))])
115
+ OrderedDict ([('type' , relation_type ), ('id' , encoding .force_text (get_pk ( related_object ) ))])
107
116
)
108
117
109
118
data .update ({field_name : {
@@ -138,7 +147,9 @@ def extract_relationships(cls, fields, resource, resource_instance):
138
147
resolved , relation = utils .get_relation_instance (resource_instance , '%s_id' % source , field .parent )
139
148
if not resolved :
140
149
continue
141
- relation_id = relation if resource .get (field_name ) else None
150
+ relation_id = get_pk (
151
+ getattr (resource_instance , source )
152
+ ) if resource .get (field_name ) else None
142
153
relation_data = {
143
154
'data' : (
144
155
OrderedDict ([('type' , relation_type ), ('id' , encoding .force_text (relation_id ))])
@@ -187,7 +198,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
187
198
188
199
relation_data .append (OrderedDict ([
189
200
('type' , nested_resource_instance_type ),
190
- ('id' , encoding .force_text (nested_resource_instance . pk ))
201
+ ('id' , encoding .force_text (get_pk ( nested_resource_instance ) ))
191
202
]))
192
203
data .update ({
193
204
field_name : {
@@ -211,14 +222,21 @@ def extract_relationships(cls, fields, resource, resource_instance):
211
222
if isinstance (serializer_data , list ):
212
223
for position in range (len (serializer_data )):
213
224
nested_resource_instance = resource_instance_queryset [position ]
225
+ nested_resource_data = serializer_data [position ]
214
226
nested_resource_instance_type = (
215
227
relation_type or
216
228
utils .get_resource_type_from_instance (nested_resource_instance )
217
229
)
218
230
231
+ instance_pk_name = nested_resource_instance ._meta .pk .name
232
+ if instance_pk_name in nested_resource_data :
233
+ pk = nested_resource_data [instance_pk_name ]
234
+ else :
235
+ pk = nested_resource_instance .pk
236
+
219
237
relation_data .append (OrderedDict ([
220
238
('type' , nested_resource_instance_type ),
221
- ('id' , encoding .force_text (nested_resource_instance . pk ))
239
+ ('id' , encoding .force_text (pk ))
222
240
]))
223
241
224
242
data .update ({field_name : {'data' : relation_data }})
@@ -234,7 +252,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
234
252
'data' : (
235
253
OrderedDict ([
236
254
('type' , relation_type ),
237
- ('id' , encoding . force_text (relation_instance . pk ))
255
+ ('id' , get_pk (relation_instance ))
238
256
]) if resource .get (field_name ) else None )
239
257
}
240
258
})
@@ -382,9 +400,17 @@ def extract_root_meta(cls, serializer, resource):
382
400
383
401
@classmethod
384
402
def build_json_resource_obj (cls , fields , resource , resource_instance , resource_name ):
403
+ if resource_instance is None :
404
+ pk = None
405
+ else :
406
+ # Check if the primary key exists in the resource by getting the primary keys attribute name.
407
+ pk_attr = resource_instance ._meta .pk .name
408
+ pk = resource [pk_attr ] if pk_attr in resource else resource_instance .pk
409
+ pk = encoding .force_text (pk )
410
+
385
411
resource_data = [
386
412
('type' , resource_name ),
387
- ('id' , encoding . force_text ( resource_instance . pk ) if resource_instance else None ),
413
+ ('id' , pk ),
388
414
('attributes' , cls .extract_attributes (fields , resource )),
389
415
]
390
416
relationships = cls .extract_relationships (fields , resource , resource_instance )
0 commit comments