@@ -34,6 +34,18 @@ record count and a `links` object with the next, previous, first, and last links
34
34
Pages can be selected with the ` page ` GET parameter. Page size can be controlled
35
35
per request via the ` PAGINATE_BY_PARAM ` query parameter (` page_size ` by default).
36
36
37
+ ### Serializers
38
+
39
+ It is recommended to import the base serializer classes from this package
40
+ rather than from vanilla DRF. For example,
41
+
42
+ ``` python
43
+ from rest_framework_json_api import serializers
44
+
45
+ class MyModelSerializer (serializers .ModelSerializers ):
46
+ # ...
47
+ ```
48
+
37
49
### Setting the resource_name
38
50
39
51
You may manually set the ` resource_name ` property on views, serializers, or
@@ -248,6 +260,160 @@ When set to pluralize:
248
260
Both ` JSON_API_PLURALIZE_RELATION_TYPE ` and ` JSON_API_FORMAT_RELATION_KEYS ` can be combined to
249
261
achieve different results.
250
262
263
+ ### Related fields
264
+
265
+ Because of the additional structure needed to represent relationships in JSON
266
+ API, this package provides the ` ResourceRelatedField ` for serializers, which
267
+ works similarly to ` PrimaryKeyRelatedField ` . By default,
268
+ ` rest_framework_json_api.serializers.ModelSerializer ` will use this for
269
+ related fields automatically. It can be instantiated explicitly as in the
270
+ following example:
271
+
272
+ ``` python
273
+ from rest_framework_json_api import serializers
274
+ from rest_framework_json_api.relations import ResourceRelatedField
275
+
276
+ from myapp.models import Order, LineItem, Customer
277
+
278
+
279
+ class OrderSerializer (serializers .ModelSerializer ):
280
+ class Meta :
281
+ model = Order
282
+
283
+ line_items = ResourceRelatedField(
284
+ queryset = LineItem.objects,
285
+ many = True # necessary for M2M fields & reverse FK fields
286
+ )
287
+
288
+ customer = ResourceRelatedField(
289
+ queryset = Customer.objects # queryset argument is required
290
+ ) # except when read_only=True
291
+
292
+ ```
293
+
294
+ In the [ JSON API spec] ( http://jsonapi.org/format/#document-resource-objects ) ,
295
+ relationship objects contain links to related objects. To make this work
296
+ on a serializer we need to tell the ` ResourceRelatedField ` about the
297
+ corresponding view. Use the ` HyperlinkedModelSerializer ` and instantiate
298
+ the ` ResourceRelatedField ` with the relevant keyword arguments:
299
+
300
+ ``` python
301
+ from rest_framework_json_api import serializers
302
+ from rest_framework_json_api.relations import ResourceRelatedField
303
+
304
+ from myapp.models import Order, LineItem, Customer
305
+
306
+
307
+ class OrderSerializer (serializers .ModelSerializer ):
308
+ class Meta :
309
+ model = Order
310
+
311
+ line_items = ResourceRelatedField(
312
+ queryset = LineItem.objects,
313
+ many = True ,
314
+ related_link_view_name = ' order-lineitems-list' ,
315
+ related_link_url_kwarg = ' order_pk' ,
316
+ self_link_view_name = ' order_relationships'
317
+ )
318
+
319
+ customer = ResourceRelatedField(
320
+ queryset = Customer.objects,
321
+ related_link_view- name = ' order-customer-detail' ,
322
+ related_link_url_kwarg = ' order_pk' ,
323
+ self_link_view_name = ' order-relationships'
324
+ )
325
+ ```
326
+
327
+ * ` related_link_view_name ` is the name of the route for the related
328
+ view.
329
+
330
+ * ` related_link_url_kwarg ` is the keyword argument that will be passed
331
+ to the view that identifies the 'parent' object, so that the results
332
+ can be filtered to show only those objects related to the 'parent'.
333
+
334
+ * ` self_link_view_name ` is the name of the route for the ` RelationshipView `
335
+ (see below).
336
+
337
+ In this example, ` reverse('order-lineitems-list', kwargs={'order_pk': 3} `
338
+ should resolve to something like ` /orders/3/lineitems ` , and that route
339
+ should instantiate a view or viewset for ` LineItem ` objects that accepts
340
+ a keword argument ` order_pk ` . The
341
+ [ drf-nested-routers] ( https://github.com/alanjds/drf-nested-routers ) package
342
+ is useful for defining such nested routes in your urlconf.
343
+
344
+ The corresponding viewset for the ` line-items-list ` route in the above example
345
+ might look like the following. Note that in the typical use case this would be
346
+ the same viewset used for the ` /lineitems ` endpoints; when accessed through
347
+ the nested route ` /orders/<order_pk>/lineitems ` the queryset is filtered using
348
+ the ` order_pk ` keyword argument to include only the lineitems related to the
349
+ specified order.
350
+
351
+ ``` python
352
+ from rest_framework import viewsets
353
+
354
+ from myapp.models import LineItem
355
+ from myapp.serializers import LineItemSerializer
356
+
357
+
358
+ class LineItemViewSet (viewsets .ModelViewSet ):
359
+ queryset = LineItem.objects
360
+ serializer_class = LineItemSerializer
361
+
362
+ def get_queryset (self ):
363
+ queryset = self .queryset
364
+
365
+ # if this viewset is accessed via the 'order-lineitems-list' route,
366
+ # it wll have been passed the `order_pk` kwarg and the queryset
367
+ # needs to be filtered accordingly; if it was accessed via the
368
+ # unnested '/lineitems' route, the queryset should include all LineItems
369
+ if ' order_pk' in self .kwargs:
370
+ order_pk = self .kwargs[' order_pk' ]
371
+ queryset = queryset.filter(order__pk = order_pk])
372
+
373
+ return queryset
374
+ ```
375
+
376
+ ### RelationshipView
377
+ ` rest_framework_json_api.views.RelationshipView ` is used to build
378
+ relationship views (see the
379
+ [ JSON API spec] ( http://jsonapi.org/format/#fetching-relationships ) ).
380
+ The ` self ` link on a relationship object should point to the corresponding
381
+ relationship view.
382
+
383
+ The relationship view is fairly simple because it only serializes
384
+ [ Resource Identifier Objects] ( http://jsonapi.org/format/#document-resource-identifier-objects )
385
+ rather than full resource objects. In most cases the following is sufficient:
386
+
387
+ ``` python
388
+ from rest_framework_json_api.views import RelationshipView
389
+
390
+ from myapp.models import Order
391
+
392
+
393
+ class OrderRelationshipView (RelationshipView ):
394
+ queryset = Order.objects
395
+
396
+ ```
397
+
398
+ The urlconf would need to contain a route like the following:
399
+
400
+ ``` python
401
+ url(
402
+ regex = r ' ^ orders/( ?P<pk> [^ /. ]+ /relationships/( ?P<related_field> [^ /. ]+ ) $ ' ,
403
+ view = OrderRelationshipView.as_view(),
404
+ name = ' order-relationships'
405
+ )
406
+ ```
407
+
408
+ The ` related_field ` kwarg specifies which relationship to use, so
409
+ if we are interested in the relationship represented by the related
410
+ model field ` Order.line_items ` on the Order with pk 3, the url would be
411
+ ` /order/3/relationships/line_items ` . On ` HyperlinkedModelSerializer ` , the
412
+ ` ResourceRelatedField ` will construct the url based on the provided
413
+ ` self_link_view_name ` keyword argument, which should match the ` name= `
414
+ provided in the urlconf, and will use the name of the field for the
415
+ ` related_field ` kwarg.
416
+
251
417
### Meta
252
418
253
419
You may add metadata to the rendered json in two different ways: ` meta_fields ` and ` get_root_meta ` .
0 commit comments