From 3a162b7e338c4d5eb55f24b7be7fd2b8d177b8fb Mon Sep 17 00:00:00 2001 From: Bart Vandendriessche Date: Mon, 10 Feb 2014 17:31:45 +0100 Subject: [PATCH] Make view kwargs available to HyperLinkedIdentityField and HyperlinkedRelatedField --- rest_framework/relations.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 02185c2ff..b3ecc6ccf 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -358,8 +358,13 @@ class HyperlinkedRelatedField(RelatedField): May raise a `NoReverseMatch` if the `view_name` and `lookup_field` attributes are not configured to correctly match the URL conf. """ + view_kwargs = {} + if self.context.get('view'): + view_kwargs = self.context['view'].kwargs + lookup_field = getattr(obj, self.lookup_field) - kwargs = {self.lookup_field: lookup_field} + kwargs = dict(view_kwargs.items() + {self.lookup_field: lookup_field}.items()) + try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: @@ -369,7 +374,8 @@ class HyperlinkedRelatedField(RelatedField): # Only try pk if it has been explicitly set. # Otherwise, the default `lookup_field = 'pk'` has us covered. pk = obj.pk - kwargs = {self.pk_url_kwarg: pk} + kwargs = dict(view_kwargs.items() + {self.pk_url_kwarg: pk}.items()) + try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: @@ -378,7 +384,8 @@ class HyperlinkedRelatedField(RelatedField): slug = getattr(obj, self.slug_field, None) if slug is not None: # Only try slug if it corresponds to an attribute on the object. - kwargs = {self.slug_url_kwarg: slug} + kwargs = dict(view_kwargs.items() + {self.slug_url_kwarg: slug}.items()) + try: ret = reverse(view_name, kwargs=kwargs, request=request, format=format) if self.slug_field == 'slug' and self.slug_url_kwarg == 'slug': @@ -565,12 +572,18 @@ class HyperlinkedIdentityField(Field): attributes are not configured to correctly match the URL conf. """ lookup_field = getattr(obj, self.lookup_field, None) - kwargs = {self.lookup_field: lookup_field} + # Handle unsaved object case if lookup_field is None: return None + view_kwargs = {} + if self.context.get('view'): + view_kwargs = self.context['view'].kwargs + + kwargs = dict(view_kwargs.items() + {self.lookup_field: lookup_field}.items()) + try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: @@ -579,7 +592,8 @@ class HyperlinkedIdentityField(Field): if self.pk_url_kwarg != 'pk': # Only try pk lookup if it has been explicitly set. # Otherwise, the default `lookup_field = 'pk'` has us covered. - kwargs = {self.pk_url_kwarg: obj.pk} + kwargs = dict(view_kwargs.items() + {self.pk_url_kwarg: obj.pk}.items()) + try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: @@ -588,7 +602,8 @@ class HyperlinkedIdentityField(Field): slug = getattr(obj, self.slug_field, None) if slug: # Only use slug lookup if a slug field exists on the model - kwargs = {self.slug_url_kwarg: slug} + kwargs = dict(view_kwargs.items() + {self.slug_url_kwarg: slug}.items()) + try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: