diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 6f8d4dabb..313a39f2e 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -320,6 +320,16 @@ class HyperlinkedRelatedField(RelatedField): view_name = self.view_name request = self.context.get('request', None) format = self.format or self.context.get('format', None) + pk = getattr(obj, 'pk', None) + if pk is None: + return + kwargs = {self.pk_url_kwarg: pk} + new_kwargs = None + + visit = self.context.get('view', None) + if visit: + new_kwargs = kwargs.copy() + new_kwargs.update(visit.kwargs) if request is None: warnings.warn("Using `HyperlinkedRelatedField` without including the " @@ -327,15 +337,16 @@ class HyperlinkedRelatedField(RelatedField): "Add `context={'request': request}` when instantiating the serializer.", PendingDeprecationWarning, stacklevel=4) - pk = getattr(obj, 'pk', None) - if pk is None: - return - kwargs = {self.pk_url_kwarg: pk} try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass + try: + return reverse(view_name, kwargs=new_kwargs, request=request, format=format) + except NoReverseMatch: + pass + slug = getattr(obj, self.slug_field, None) if not slug: @@ -435,11 +446,12 @@ class HyperlinkedIdentityField(Field): format = self.context.get('format', None) view_name = self.view_name or self.parent.opts.view_name kwargs = {self.pk_url_kwarg: obj.pk} + new_kwargs = None - #get any extra kwargs from the view url and make sure we pass them through to reverse visit = self.context.get('view', None) if visit: - kwargs.update(visit.kwargs) + new_kwargs = kwargs.copy() + new_kwargs.update(visit.kwargs) if request is None: warnings.warn("Using `HyperlinkedIdentityField` without including the " @@ -464,6 +476,11 @@ class HyperlinkedIdentityField(Field): except NoReverseMatch: pass + try: + return reverse(view_name, kwargs=new_kwargs, request=request, format=format) + except NoReverseMatch: + pass + slug = getattr(obj, self.slug_field, None) if not slug: diff --git a/rest_framework/tests/hyperlinkedserializers.py b/rest_framework/tests/hyperlinkedserializers.py index 4bde66605..ada41a2cc 100644 --- a/rest_framework/tests/hyperlinkedserializers.py +++ b/rest_framework/tests/hyperlinkedserializers.py @@ -80,9 +80,13 @@ class OptionalRelationDetail(generics.RetrieveUpdateDestroyAPIView): model_serializer_class = serializers.HyperlinkedModelSerializer +class ExtraKwargDetailSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = ExtraKwargModel + class ExtraKwargDetail(generics.RetrieveUpdateDestroyAPIView): model = ExtraKwargModel - model_serializer_class = serializers.HyperlinkedModelSerializer + serializer_class = ExtraKwargDetailSerializer urlpatterns = patterns('', url(r'^basic/$', BasicList.as_view(), name='basicmodel-list'), @@ -275,7 +279,8 @@ class TestNestedRelationHyperlinkedView(TestCase): """ Create 1 ExtraKwargModel instance. """ - ExtraKwargModel().save() + self.basic = BasicModel.objects.create() + self.model = ExtraKwargModel.objects.create(basic=self.basic) self.objects = ExtraKwargModel.objects self.detail_view = ExtraKwargDetail.as_view() diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index fd56dc08d..66359d3da 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -125,7 +125,7 @@ class OptionalRelationModel(RESTFrameworkModel): # Model to test multiple kwargs in url class ExtraKwargModel(RESTFrameworkModel): - pass + basic = models.ForeignKey(BasicModel) # Model for RegexField class Book(RESTFrameworkModel):