This commit is contained in:
Nick Johnson 2013-05-01 01:02:11 -07:00
commit 82cb84e69d
3 changed files with 59 additions and 5 deletions

View File

@ -319,6 +319,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 "
@ -326,15 +336,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:
@ -434,6 +445,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
visit = self.context.get('view', None)
if visit:
new_kwargs = kwargs.copy()
new_kwargs.update(visit.kwargs)
if request is None:
warnings.warn("Using `HyperlinkedIdentityField` without including the "
@ -458,6 +475,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:

View File

@ -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,14 @@ class OptionalRelationDetail(generics.RetrieveUpdateDestroyAPIView):
model_serializer_class = serializers.HyperlinkedModelSerializer
class ExtraKwargDetailSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ExtraKwargModel
class ExtraKwargDetail(generics.RetrieveUpdateDestroyAPIView):
model = ExtraKwargModel
serializer_class = ExtraKwargDetailSerializer
urlpatterns = patterns('',
url(r'^basic/$', BasicList.as_view(), name='basicmodel-list'),
url(r'^basic/(?P<pk>\d+)/$', BasicDetail.as_view(), name='basicmodel-detail'),
@ -92,6 +100,7 @@ urlpatterns = patterns('',
url(r'^albums/(?P<title>\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 +270,23 @@ 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.
"""
self.basic = BasicModel.objects.create()
self.model = ExtraKwargModel.objects.create(basic=self.basic)
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)

View File

@ -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):
basic = models.ForeignKey(BasicModel)
# Model for RegexField
class Book(RESTFrameworkModel):