From 2cb2cc7f9be9939b7aca3fcb7fb2f4845e90ec98 Mon Sep 17 00:00:00 2001 From: Christian Sauer Date: Mon, 26 Dec 2016 14:39:02 -0500 Subject: [PATCH] Separate kwargs from lookup in HyperlinkedRelatedField.get_object/get_url DRF extensions, like DRF-nested-routers, can have more lookups than just the PK. Currently would need to completely re-implement get_object/get_url instead of just adding to the lookup dict. --- rest_framework/relations.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/rest_framework/relations.py b/rest_framework/relations.py index c1898d0d8..5fa33ba95 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -291,10 +291,18 @@ class HyperlinkedRelatedField(RelatedField): Takes the matched URL conf arguments, and should return an object instance, or raise an `ObjectDoesNotExist` exception. """ - lookup_value = view_kwargs[self.lookup_url_kwarg] - lookup_kwargs = {self.lookup_field: lookup_value} + lookup_kwargs = self.get_object_kwargs(view_name, view_args, view_kwargs) return self.get_queryset().get(**lookup_kwargs) + def get_object_kwargs(self, view_name, view_args, view_kwargs): + """ + Get default kwargs for looking up an object. + + Separate for subclassing purposes. + """ + lookup_value = view_kwargs[self.lookup_url_kwarg] + return {self.lookup_field: lookup_value} + def get_url(self, obj, view_name, request, format): """ Given an object, return the URL that hyperlinks to the object. @@ -306,10 +314,18 @@ class HyperlinkedRelatedField(RelatedField): if hasattr(obj, 'pk') and obj.pk in (None, ''): return None - lookup_value = getattr(obj, self.lookup_field) - kwargs = {self.lookup_url_kwarg: lookup_value} + kwargs = self.get_url_kwargs(obj, view_name, request, format) return self.reverse(view_name, kwargs=kwargs, request=request, format=format) + def get_url_kwargs(self, obj, view_name, request, format): + """ + Get default kwargs for creating the object's URL. + + Separate for subclassing purposes. + """ + lookup_value = getattr(obj, self.lookup_field) + return {self.lookup_url_kwarg: lookup_value} + def to_internal_value(self, data): request = self.context.get('request', None) try: