added tests for url switch in fields

This commit is contained in:
Stephan Groß 2012-12-13 12:32:28 +01:00
parent 11375127e2
commit f7497a2c0a
3 changed files with 69 additions and 8 deletions

View File

@ -543,6 +543,9 @@ class HyperlinkedRelatedField(RelatedField):
self.slug_url_kwarg = kwargs.pop('slug_url_kwarg', default_slug_kwarg)
self.format = kwargs.pop('format', None)
self.use_absolute_urls = kwargs.pop('use_absolute_urls', self.parent.use_absolute_urls)
super(HyperlinkedRelatedField, self).__init__(*args, **kwargs)
def get_slug_field(self):
@ -555,12 +558,13 @@ class HyperlinkedRelatedField(RelatedField):
view_name = self.view_name
request = self.context.get('request', None)
format = self.format or self.context.get('format', None)
use_absolute_urls = self.use_absolute_urls
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)
return reverse(view_name, kwargs=kwargs, request=request, format=format, use_absolute_urls=use_absolute_urls)
except:
pass
@ -571,13 +575,13 @@ class HyperlinkedRelatedField(RelatedField):
kwargs = {self.slug_url_kwarg: slug}
try:
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
return reverse(self.view_name, kwargs=kwargs, request=request, format=format, use_absolute_urls=use_absolute_urls)
except:
pass
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
try:
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
return reverse(self.view_name, kwargs=kwargs, request=request, format=format, use_absolute_urls=use_absolute_urls)
except:
pass
@ -651,6 +655,8 @@ class HyperlinkedIdentityField(Field):
self.pk_url_kwarg = kwargs.pop('pk_url_kwarg', self.pk_url_kwarg)
self.slug_url_kwarg = kwargs.pop('slug_url_kwarg', default_slug_kwarg)
self.use_absolute_urls = kwargs.pop('use_absolute_urls', self.parent.use_absolute_urls)
super(HyperlinkedIdentityField, self).__init__(*args, **kwargs)
def field_to_native(self, obj, field_name):
@ -658,8 +664,9 @@ class HyperlinkedIdentityField(Field):
format = self.format or self.context.get('format', None)
view_name = self.view_name or self.parent.opts.view_name
kwargs = {self.pk_url_kwarg: obj.pk}
use_absolute_urls = self.use_absolute_urls
try:
return reverse(view_name, kwargs=kwargs, request=request, format=format)
return reverse(view_name, kwargs=kwargs, request=request, format=format, use_absolute_urls=use_absolute_urls)
except:
pass
@ -670,13 +677,13 @@ class HyperlinkedIdentityField(Field):
kwargs = {self.slug_url_kwarg: slug}
try:
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
return reverse(self.view_name, kwargs=kwargs, request=request, format=format, use_absolute_urls=use_absolute_urls)
except:
pass
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
try:
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
return reverse(self.view_name, kwargs=kwargs, request=request, format=format, use_absolute_urls=use_absolute_urls)
except:
pass

View File

@ -6,7 +6,7 @@ from django.utils.functional import lazy
from rest_framework.settings import api_settings
def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra):
def reverse(viewname, args=None, kwargs=None, request=None, format=None, use_absolute_urls=api_settings.USE_ABSOLUTE_URLS, **extra):
"""
Same as `django.core.urlresolvers.reverse`, but optionally takes a request
and returns a fully qualified URL, using the request to get the base URL.
@ -15,7 +15,7 @@ def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra
kwargs = kwargs or {}
kwargs['format'] = format
url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
if api_settings.USE_ABSOLUTE_URLS:
if use_absolute_urls:
assert request, "request is required for building absolute url"
url = request.build_absolute_uri(url)
return url

View File

@ -26,6 +26,14 @@ class PhotoSerializer(serializers.Serializer):
return Photo(**attrs)
class PhotoUrlSerializer(PhotoSerializer):
url = serializers.HyperlinkedIdentityField(view_name='photoswithabsoluteurls-detail', use_absolute_urls=True)
class Meta:
model = Photo
use_absolute_urls = False
class BasicList(generics.ListCreateAPIView):
model = BasicModel
model_serializer_class = serializers.HyperlinkedModelSerializer
@ -74,6 +82,16 @@ class AlbumDetail(generics.RetrieveAPIView):
model = Album
class PhotoUrlList(generics.ListAPIView):
model = Photo
serializer_class = PhotoUrlSerializer
class PhotoUrlDetail(generics.RetrieveAPIView):
model = Photo
serializer_class = PhotoUrlSerializer
class OptionalRelationDetail(generics.RetrieveUpdateDestroyAPIView):
model = OptionalRelationModel
model_serializer_class = serializers.HyperlinkedModelSerializer
@ -90,6 +108,8 @@ urlpatterns = patterns('',
url(r'^comments/(?P<pk>\d+)/$', BlogPostCommentDetail.as_view(), name='blogpostcomment-detail'),
url(r'^albums/(?P<title>\w[\w-]*)/$', AlbumDetail.as_view(), name='album-detail'),
url(r'^photos/$', PhotoListCreate.as_view(), name='photo-list'),
url(r'^photos-with-absolute-urls/$', PhotoAbsoluteUrlList.as_view(), name='photoswithabsoluteurls-list'),
url(r'^photos-with-absolute-urls/(?P<pk>\d+)/$', PhotoAbsoluteUrlDetail.as_view(), name='photoswithabsoluteurls-detail'),
url(r'^optionalrelation/(?P<pk>\d+)/$', OptionalRelationDetail.as_view(), name='optionalrelationmodel-detail'),
)
@ -260,3 +280,37 @@ class TestOptionalRelationHyperlinkedView(TestCase):
data=json.dumps(self.data),
content_type='application/json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
class TestUrlOptionsView(TestCase):
urls = 'rest_framework.tests.hyperlinkedserializers'
def setUp(self):
"""
Create a album and photos
"""
self.album = Album.objects.create(title="Test album")
items = ['beach', 'sunset', 'moon']
for item in items:
Photo(description=item, album=self.album).save()
self.objects = Photo.objects
self.data = [
{
'url': '/photos-with-absolute-urls/%d/' % obj.id,
'description': obj.text,
'album_url': 'http://testserver/optionalrelation/%d/' % obj.album
}
for obj in self.objects.all()
]
self.list_view = PhotoUrlList.as_view()
self.detail_view = PhotoUrlDetail.as_view()
def test_get_detail_view(self):
"""
GET requests to RetrieveAPIView with optional relations should return None
for non existing relations.
"""
request = factory.get('/photos-with-absolute-urls/1')
response = self.detail_view(request)
self.assertEquals(response.status_code, status.HTTP_200_OK)
self.assertEquals(response.data, self.data[0:2])