Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ model field `Order.line_items` on the Order with pk 3, the url would be
`self_link_view_name` keyword argument, which should match the `name=`
provided in the urlconf, and will use the name of the field for the
`related_field` kwarg.
Also we can override `related_field` in the url. Let's say we want the url to be:
`/order/3/relationships/order_items` - all we need to do is just add `field_name_mapping`
dict to the class:
```python
field_name_mapping = {
'line_items': 'order_items'
}
```


### Meta

Expand Down
13 changes: 10 additions & 3 deletions rest_framework_json_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class RelationshipView(generics.GenericAPIView):
serializer_class = ResourceIdentifierObjectSerializer
self_link_view_name = None
related_link_view_name = None
field_name_mapping = {}

def get_serializer_class(self):
if getattr(self, 'action', False) is None:
Expand Down Expand Up @@ -96,7 +97,7 @@ def patch(self, request, *args, **kwargs):
related_model_class = related_instance_or_manager.__class__
serializer = self.get_serializer(data=request.data, model_class=related_model_class)
serializer.is_valid(raise_exception=True)
setattr(parent_obj, kwargs['related_field'], serializer.validated_data)
setattr(parent_obj, self.get_related_field_name(), serializer.validated_data)
parent_obj.save()
result_serializer = self._instantiate_serializer(related_instance_or_manager)
return Response(result_serializer.data)
Expand Down Expand Up @@ -138,10 +139,16 @@ def delete(self, request, *args, **kwargs):

def get_related_instance(self):
try:
return getattr(self.get_object(), self.kwargs['related_field'])
return getattr(self.get_object(), self.get_related_field_name())
except AttributeError:
raise NotFound

def get_related_field_name(self):
field_name = self.kwargs['related_field']
if field_name in self.field_name_mapping:
return self.field_name_mapping[field_name]
return field_name

def _instantiate_serializer(self, instance):
if isinstance(instance, Model) or instance is None:
return self.get_serializer(instance=instance)
Expand All @@ -153,7 +160,7 @@ def _instantiate_serializer(self, instance):

def get_resource_name(self):
if not hasattr(self, '_resource_name'):
instance = getattr(self.get_object(), self.kwargs['related_field'])
instance = getattr(self.get_object(), self.get_related_field_name())
self._resource_name = get_resource_type_from_instance(instance)
return self._resource_name

Expand Down