mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-02 20:54:42 +03:00
Fixes for urls with suffixes
This commit is contained in:
parent
ee8ab283f0
commit
d206c686a6
|
@ -31,14 +31,6 @@ class PermissionDenied(APIException):
|
||||||
self.detail = detail or self.default_detail
|
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):
|
class MethodNotAllowed(APIException):
|
||||||
status_code = status.HTTP_405_METHOD_NOT_ALLOWED
|
status_code = status.HTTP_405_METHOD_NOT_ALLOWED
|
||||||
default_detail = "Method '%s' not allowed."
|
default_detail = "Method '%s' not allowed."
|
||||||
|
|
|
@ -331,14 +331,16 @@ class HyperlinkedRelatedField(RelatedField):
|
||||||
self.view_name = kwargs.pop('view_name')
|
self.view_name = kwargs.pop('view_name')
|
||||||
except:
|
except:
|
||||||
raise ValueError("Hyperlinked field requires 'view_name' kwarg")
|
raise ValueError("Hyperlinked field requires 'view_name' kwarg")
|
||||||
|
self.format = kwargs.pop('format', None)
|
||||||
super(HyperlinkedRelatedField, self).__init__(*args, **kwargs)
|
super(HyperlinkedRelatedField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def to_native(self, obj):
|
def to_native(self, obj):
|
||||||
view_name = self.view_name
|
view_name = self.view_name
|
||||||
request = self.context.get('request', None)
|
request = self.context.get('request', None)
|
||||||
|
format = self.format or self.context.get('format', None)
|
||||||
kwargs = {self.pk_url_kwarg: obj.pk}
|
kwargs = {self.pk_url_kwarg: obj.pk}
|
||||||
try:
|
try:
|
||||||
return reverse(view_name, kwargs=kwargs, request=request)
|
return reverse(view_name, kwargs=kwargs, request=request, format=format)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -349,13 +351,13 @@ class HyperlinkedRelatedField(RelatedField):
|
||||||
|
|
||||||
kwargs = {self.slug_url_kwarg: slug}
|
kwargs = {self.slug_url_kwarg: slug}
|
||||||
try:
|
try:
|
||||||
return reverse(self.view_name, kwargs=kwargs, request=request)
|
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
|
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
|
||||||
try:
|
try:
|
||||||
return reverse(self.view_name, kwargs=kwargs, request=request)
|
return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -405,13 +407,15 @@ class HyperlinkedIdentityField(Field):
|
||||||
# TODO: Make this mandatory, and have the HyperlinkedModelSerializer
|
# TODO: Make this mandatory, and have the HyperlinkedModelSerializer
|
||||||
# set it on-the-fly
|
# set it on-the-fly
|
||||||
self.view_name = kwargs.pop('view_name', None)
|
self.view_name = kwargs.pop('view_name', None)
|
||||||
|
self.format = kwargs.pop('format', None)
|
||||||
super(HyperlinkedIdentityField, self).__init__(*args, **kwargs)
|
super(HyperlinkedIdentityField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def field_to_native(self, obj, field_name):
|
def field_to_native(self, obj, field_name):
|
||||||
request = self.context.get('request', None)
|
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_name = self.view_name or self.parent.opts.view_name
|
||||||
view_kwargs = {'pk': obj.pk}
|
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 #####
|
##### Typed Fields #####
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.http import Http404
|
||||||
from rest_framework import exceptions
|
from rest_framework import exceptions
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
from rest_framework.utils.mediatypes import order_by_precedence, media_type_matches
|
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
|
renderers = [renderer for renderer in renderers
|
||||||
if renderer.format == format]
|
if renderer.format == format]
|
||||||
if not renderers:
|
if not renderers:
|
||||||
raise exceptions.InvalidFormat(format)
|
raise Http404
|
||||||
return renderers
|
return renderers
|
||||||
|
|
||||||
def get_accept_list(self, request):
|
def get_accept_list(self, request):
|
||||||
|
|
|
@ -5,13 +5,15 @@ from django.core.urlresolvers import reverse as django_reverse
|
||||||
from django.utils.functional import lazy
|
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
|
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.
|
and returns a fully qualified URL, using the request to get the base URL.
|
||||||
"""
|
"""
|
||||||
request = kwargs.pop('request', None)
|
if format is not None:
|
||||||
url = django_reverse(viewname, *args, **kwargs)
|
kwargs = kwargs or {}
|
||||||
|
kwargs['format'] = format
|
||||||
|
url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
|
||||||
if request:
|
if request:
|
||||||
return request.build_absolute_uri(url)
|
return request.build_absolute_uri(url)
|
||||||
return url
|
return url
|
||||||
|
|
Loading…
Reference in New Issue
Block a user