diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 0c108717f..6f8d4dabb 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -436,6 +436,11 @@ class HyperlinkedIdentityField(Field): view_name = self.view_name or self.parent.opts.view_name kwargs = {self.pk_url_kwarg: obj.pk} + #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) + if request is None: warnings.warn("Using `HyperlinkedIdentityField` without including the " "request in the serializer context is due to be deprecated. " diff --git a/rest_framework/tests/hyperlinkedserializers.py b/rest_framework/tests/hyperlinkedserializers.py index 589c30b61..4bde66605 100644 --- a/rest_framework/tests/hyperlinkedserializers.py +++ b/rest_framework/tests/hyperlinkedserializers.py @@ -4,7 +4,7 @@ from django.test import TestCase from django.test.client import RequestFactory from rest_framework import generics, status, serializers from rest_framework.compat import patterns, url -from rest_framework.tests.models import Anchor, BasicModel, ManyToManyModel, BlogPost, BlogPostComment, Album, Photo, OptionalRelationModel +from rest_framework.tests.models import Anchor, BasicModel, ManyToManyModel, BlogPost, BlogPostComment, Album, Photo, OptionalRelationModel, ExtraKwargModel factory = RequestFactory() @@ -80,6 +80,10 @@ class OptionalRelationDetail(generics.RetrieveUpdateDestroyAPIView): model_serializer_class = serializers.HyperlinkedModelSerializer +class ExtraKwargDetail(generics.RetrieveUpdateDestroyAPIView): + model = ExtraKwargModel + model_serializer_class = serializers.HyperlinkedModelSerializer + urlpatterns = patterns('', url(r'^basic/$', BasicList.as_view(), name='basicmodel-list'), url(r'^basic/(?P\d+)/$', BasicDetail.as_view(), name='basicmodel-detail'), @@ -92,6 +96,7 @@ urlpatterns = patterns('', url(r'^albums/(?P\w[\w-]*)/$', AlbumDetail.as_view(), name='album-detail'), url(r'^photos/$', PhotoListCreate.as_view(), name='photo-list'), url(r'^optionalrelation/(?P<pk>\d+)/$', OptionalRelationDetail.as_view(), name='optionalrelationmodel-detail'), + url(r'^root/(?P<extra_kwarg>\d+)/extrakwarg/(?P<pk>\d+)/$', ExtraKwargDetail.as_view(), name='extrakwargmodel-detail'), ) @@ -261,3 +266,22 @@ class TestOptionalRelationHyperlinkedView(TestCase): data=json.dumps(self.data), content_type='application/json') self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class TestNestedRelationHyperlinkedView(TestCase): + urls = 'rest_framework.tests.hyperlinkedserializers' + + def setUp(self): + """ + Create 1 ExtraKwargModel instance. + """ + ExtraKwargModel().save() + self.objects = ExtraKwargModel.objects + self.detail_view = ExtraKwargDetail.as_view() + + def test_get_detail_view(self): + """ + GET requests to a detail url with more than one kwarg should still resolve using reverse + """ + response = self.client.get('/root/2/extrakwarg/1/') + self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index f2117538c..fd56dc08d 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -123,6 +123,9 @@ class BlankFieldModel(RESTFrameworkModel): class OptionalRelationModel(RESTFrameworkModel): other = models.ForeignKey('OptionalRelationModel', blank=True, null=True) +# Model to test multiple kwargs in url +class ExtraKwargModel(RESTFrameworkModel): + pass # Model for RegexField class Book(RESTFrameworkModel):