@@ -34,6 +34,18 @@ record count and a `links` object with the next, previous, first, and last links
3434Pages can be selected with the ` page ` GET parameter. Page size can be controlled
3535per request via the ` PAGINATE_BY_PARAM ` query parameter (` page_size ` by default).
3636
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+
3749### Setting the resource_name
3850
3951You may manually set the ` resource_name ` property on views, serializers, or
@@ -248,6 +260,160 @@ When set to pluralize:
248260Both ` JSON_API_PLURALIZE_RELATION_TYPE ` and ` JSON_API_FORMAT_RELATION_KEYS ` can be combined to
249261achieve different results.
250262
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+
251417### Meta
252418
253419You may add metadata to the rendered json in two different ways: ` meta_fields ` and ` get_root_meta ` .
0 commit comments