diff options
| author | Tom Christie | 2012-10-29 17:08:38 +0000 |
|---|---|---|
| committer | Tom Christie | 2012-10-29 17:08:38 +0000 |
| commit | d206c686a643b7cc720743d8dab207e8ad0280f8 (patch) | |
| tree | e11234f0f3c3f11e9b5edceed239ad238d59d09e | |
| parent | ee8ab283f091b73e284c74a11882f910a04eb2de (diff) | |
| download | django-rest-framework-d206c686a643b7cc720743d8dab207e8ad0280f8.tar.bz2 | |
Fixes for urls with suffixes
| -rw-r--r-- | rest_framework/exceptions.py | 8 | ||||
| -rw-r--r-- | rest_framework/fields.py | 12 | ||||
| -rw-r--r-- | rest_framework/negotiation.py | 3 | ||||
| -rw-r--r-- | rest_framework/reverse.py | 8 |
4 files changed, 15 insertions, 16 deletions
diff --git a/rest_framework/exceptions.py b/rest_framework/exceptions.py index 572425b9..89479deb 100644 --- a/rest_framework/exceptions.py +++ b/rest_framework/exceptions.py @@ -31,14 +31,6 @@ class PermissionDenied(APIException): self.detail = detail or self.default_detail -class InvalidFormat(APIException): - status_code = status.HTTP_404_NOT_FOUND - default_detail = "Format suffix '.%s' not found." - - def __init__(self, format, detail=None): - self.detail = (detail or self.default_detail) % format - - class MethodNotAllowed(APIException): status_code = status.HTTP_405_METHOD_NOT_ALLOWED default_detail = "Method '%s' not allowed." diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 03c01a88..f9de7cf9 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -331,14 +331,16 @@ class HyperlinkedRelatedField(RelatedField): self.view_name = kwargs.pop('view_name') except: raise ValueError("Hyperlinked field requires 'view_name' kwarg") + self.format = kwargs.pop('format', None) super(HyperlinkedRelatedField, self).__init__(*args, **kwargs) def to_native(self, obj): view_name = self.view_name request = self.context.get('request', None) + format = self.format or self.context.get('format', None) kwargs = {self.pk_url_kwarg: obj.pk} try: - return reverse(view_name, kwargs=kwargs, request=request) + return reverse(view_name, kwargs=kwargs, request=request, format=format) except: pass @@ -349,13 +351,13 @@ class HyperlinkedRelatedField(RelatedField): kwargs = {self.slug_url_kwarg: slug} try: - return reverse(self.view_name, kwargs=kwargs, request=request) + return reverse(self.view_name, kwargs=kwargs, request=request, format=format) except: pass kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug} try: - return reverse(self.view_name, kwargs=kwargs, request=request) + return reverse(self.view_name, kwargs=kwargs, request=request, format=format) except: pass @@ -405,13 +407,15 @@ class HyperlinkedIdentityField(Field): # TODO: Make this mandatory, and have the HyperlinkedModelSerializer # set it on-the-fly self.view_name = kwargs.pop('view_name', None) + self.format = kwargs.pop('format', None) super(HyperlinkedIdentityField, self).__init__(*args, **kwargs) def field_to_native(self, obj, field_name): request = self.context.get('request', None) + format = self.format or self.context.get('format', None) view_name = self.view_name or self.parent.opts.view_name view_kwargs = {'pk': obj.pk} - return reverse(view_name, kwargs=view_kwargs, request=request) + return reverse(view_name, kwargs=view_kwargs, request=request, format=format) ##### Typed Fields ##### diff --git a/rest_framework/negotiation.py b/rest_framework/negotiation.py index 444f8056..dae38477 100644 --- a/rest_framework/negotiation.py +++ b/rest_framework/negotiation.py @@ -1,3 +1,4 @@ +from django.http import Http404 from rest_framework import exceptions from rest_framework.settings import api_settings from rest_framework.utils.mediatypes import order_by_precedence, media_type_matches @@ -66,7 +67,7 @@ class DefaultContentNegotiation(BaseContentNegotiation): renderers = [renderer for renderer in renderers if renderer.format == format] if not renderers: - raise exceptions.InvalidFormat(format) + raise Http404 return renderers def get_accept_list(self, request): diff --git a/rest_framework/reverse.py b/rest_framework/reverse.py index ba663f98..c9db02f0 100644 --- a/rest_framework/reverse.py +++ b/rest_framework/reverse.py @@ -5,13 +5,15 @@ from django.core.urlresolvers import reverse as django_reverse from django.utils.functional import lazy -def reverse(viewname, *args, **kwargs): +def reverse(viewname, args=None, kwargs=None, request=None, format=None, **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. """ - request = kwargs.pop('request', None) - url = django_reverse(viewname, *args, **kwargs) + if format is not None: + kwargs = kwargs or {} + kwargs['format'] = format + url = django_reverse(viewname, args=args, kwargs=kwargs, **extra) if request: return request.build_absolute_uri(url) return url |
