reverse gets it's own module

This commit is contained in:
Tom Christie 2012-02-21 20:47:55 +00:00
parent b7c06dd8e3
commit ca9465f11e
16 changed files with 67 additions and 56 deletions

View File

@ -457,3 +457,11 @@ except ImportError: # python < 2.7
return decorator return decorator
unittest.skip = skip unittest.skip = skip
# reverse_lazy (Django 1.4 onwards)
try:
from django.core.urlresolvers import reverse_lazy
except:
from django.core.urlresolvers import reverse
from django.utils.functional import lazy
reverse_lazy = lazy(reverse, str)

View File

@ -3,8 +3,9 @@ from django.core.urlresolvers import get_urlconf, get_resolver, NoReverseMatch
from django.db import models from django.db import models
from djangorestframework.response import ErrorResponse from djangorestframework.response import ErrorResponse
from djangorestframework.reverse import reverse
from djangorestframework.serializer import Serializer, _SkipField from djangorestframework.serializer import Serializer, _SkipField
from djangorestframework.utils import as_tuple, reverse from djangorestframework.utils import as_tuple
class BaseResource(Serializer): class BaseResource(Serializer):

View File

@ -0,0 +1,23 @@
"""
Provide reverse functions that return fully qualified URLs
"""
from django.core.urlresolvers import reverse as django_reverse
from djangorestframework.compat import reverse_lazy as django_reverse_lazy
def reverse(viewname, request, *args, **kwargs):
"""
Do the same as `django.core.urlresolvers.reverse` but using
*request* to build a fully qualified URL.
"""
url = django_reverse(viewname, *args, **kwargs)
return request.build_absolute_uri(url)
def reverse_lazy(viewname, request, *args, **kwargs):
"""
Do the same as `django.core.urlresolvers.reverse_lazy` but using
*request* to build a fully qualified URL.
"""
url = django_reverse_lazy(viewname, *args, **kwargs)
return request.build_absolute_uri(url)

View File

@ -2,27 +2,32 @@ from django.conf.urls.defaults import patterns, url
from django.test import TestCase from django.test import TestCase
from django.utils import simplejson as json from django.utils import simplejson as json
from djangorestframework.utils import reverse from djangorestframework.renderers import JSONRenderer
from djangorestframework.reverse import reverse
from djangorestframework.views import View from djangorestframework.views import View
class MockView(View): class MyView(View):
"""Mock resource which simply returns a URL, so that we can ensure that reversed URLs are fully qualified""" """
permissions = () Mock resource which simply returns a URL, so that we can ensure
that reversed URLs are fully qualified.
"""
renderers = (JSONRenderer, )
def get(self, request): def get(self, request):
return reverse('another', request) return reverse('myview', request)
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^$', MockView.as_view()), url(r'^myview$', MyView.as_view(), name='myview'),
url(r'^another$', MockView.as_view(), name='another'),
) )
class ReverseTests(TestCase): class ReverseTests(TestCase):
"""Tests for """ """
Tests for fully qualifed URLs when using `reverse`.
"""
urls = 'djangorestframework.tests.reverse' urls = 'djangorestframework.tests.reverse'
def test_reversed_urls_are_fully_qualified(self): def test_reversed_urls_are_fully_qualified(self):
response = self.client.get('/') response = self.client.get('/myview')
self.assertEqual(json.loads(response.content), 'http://testserver/another') self.assertEqual(json.loads(response.content), 'http://testserver/myview')

View File

@ -1,7 +1,7 @@
import django import django
from django.utils.encoding import smart_unicode from django.utils.encoding import smart_unicode
from django.utils.xmlutils import SimplerXMLGenerator from django.utils.xmlutils import SimplerXMLGenerator
from django.core.urlresolvers import resolve, reverse as django_reverse from django.core.urlresolvers import resolve
from django.conf import settings from django.conf import settings
from djangorestframework.compat import StringIO from djangorestframework.compat import StringIO
@ -174,21 +174,3 @@ class XMLRenderer():
def dict2xml(input): def dict2xml(input):
return XMLRenderer().dict2xml(input) return XMLRenderer().dict2xml(input)
def reverse(viewname, request, *args, **kwargs):
"""
Do the same as :py:func:`django.core.urlresolvers.reverse` but using
*request* to build a fully qualified URL.
"""
return request.build_absolute_uri(django_reverse(viewname, *args, **kwargs))
if django.VERSION >= (1, 4):
from django.core.urlresolvers import reverse_lazy as django_reverse_lazy
def reverse_lazy(viewname, request, *args, **kwargs):
"""
Do the same as :py:func:`django.core.urlresolvers.reverse_lazy` but using
*request* to build a fully qualified URL.
"""
return request.build_absolute_uri(django_reverse_lazy(viewname, *args, **kwargs))

View File

@ -1,12 +1,6 @@
Returning URIs from your Web APIs Returning URIs from your Web APIs
================================= =================================
"The central feature that distinguishes the REST architectural style from
other network-based styles is its emphasis on a uniform interface between
components."
-- Roy Fielding, Architectural Styles and the Design of Network-based Software Architectures
As a rule, it's probably better practice to return absolute URIs from you web APIs, e.g. "http://example.com/foobar", rather than returning relative URIs, e.g. "/foobar". As a rule, it's probably better practice to return absolute URIs from you web APIs, e.g. "http://example.com/foobar", rather than returning relative URIs, e.g. "/foobar".
The advantages of doing so are: The advantages of doing so are:
@ -23,9 +17,9 @@ There's no requirement for you to use them, but if you do then the self-describi
reverse(viewname, request, ...) reverse(viewname, request, ...)
------------------------------- -------------------------------
The :py:func:`~utils.reverse` function has the same behavior as :py:func:`django.core.urlresolvers.reverse` [1]_, except that it takes a request object and returns a fully qualified URL, using the request to determine the host and port:: The :py:func:`~reverse.reverse` function has the same behavior as `django.core.urlresolvers.reverse`_, except that it takes a request object and returns a fully qualified URL, using the request to determine the host and port::
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
from djangorestframework.views import View from djangorestframework.views import View
class MyView(View): class MyView(View):
@ -39,9 +33,7 @@ The :py:func:`~utils.reverse` function has the same behavior as :py:func:`django
reverse_lazy(viewname, request, ...) reverse_lazy(viewname, request, ...)
------------------------------------ ------------------------------------
The :py:func:`~utils.reverse_lazy` function has the same behavior as :py:func:`django.core.urlresolvers.reverse_lazy` [2]_, except that it takes a request object and returns a fully qualified URL, using the request to determine the host and port. The :py:func:`~reverse.reverse_lazy` function has the same behavior as `django.core.urlresolvers.reverse_lazy`_, except that it takes a request object and returns a fully qualified URL, using the request to determine the host and port.
.. rubric:: Footnotes .. _django.core.urlresolvers.reverse: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse
.. _django.core.urlresolvers.reverse_lazy: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-lazy
.. [1] https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse
.. [2] https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-lazy

5
docs/library/reverse.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`reverse`
================
.. automodule:: reverse
:members:

View File

@ -1,5 +0,0 @@
:mod:`utils`
==============
.. automodule:: utils
:members:

View File

@ -1,5 +1,5 @@
from djangorestframework.resources import ModelResource from djangorestframework.resources import ModelResource
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
from blogpost.models import BlogPost, Comment from blogpost.models import BlogPost, Comment

View File

@ -5,7 +5,7 @@ from django.test import TestCase
from django.utils import simplejson as json from django.utils import simplejson as json
from djangorestframework.compat import RequestFactory from djangorestframework.compat import RequestFactory
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
from djangorestframework.views import InstanceModelView, ListOrCreateModelView from djangorestframework.views import InstanceModelView, ListOrCreateModelView
from blogpost import models, urls from blogpost import models, urls

View File

@ -2,7 +2,7 @@ from djangorestframework.compat import View # Use Django 1.3's django.views.gen
from djangorestframework.mixins import ResponseMixin from djangorestframework.mixins import ResponseMixin
from djangorestframework.renderers import DEFAULT_RENDERERS from djangorestframework.renderers import DEFAULT_RENDERERS
from djangorestframework.response import Response from djangorestframework.response import Response
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
from django.conf.urls.defaults import patterns, url from django.conf.urls.defaults import patterns, url

View File

@ -1,6 +1,6 @@
from django.conf import settings from django.conf import settings
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
from djangorestframework.views import View from djangorestframework.views import View
from djangorestframework.response import Response from djangorestframework.response import Response
from djangorestframework import status from djangorestframework import status

View File

@ -1,6 +1,6 @@
from djangorestframework.views import View from djangorestframework.views import View
from djangorestframework.permissions import PerUserThrottling, IsAuthenticated from djangorestframework.permissions import PerUserThrottling, IsAuthenticated
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
class PermissionsExampleView(View): class PermissionsExampleView(View):

View File

@ -4,7 +4,7 @@ from django.conf import settings
from djangorestframework.resources import FormResource from djangorestframework.resources import FormResource
from djangorestframework.response import Response from djangorestframework.response import Response
from djangorestframework.renderers import BaseRenderer from djangorestframework.renderers import BaseRenderer
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
from djangorestframework.views import View from djangorestframework.views import View
from djangorestframework import status from djangorestframework import status

View File

@ -1,4 +1,4 @@
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
from djangorestframework.views import View from djangorestframework.views import View
from djangorestframework.response import Response from djangorestframework.response import Response
from djangorestframework import status from djangorestframework import status

View File

@ -1,6 +1,6 @@
"""The root view for the examples provided with Django REST framework""" """The root view for the examples provided with Django REST framework"""
from djangorestframework.utils import reverse from djangorestframework.reverse import reverse
from djangorestframework.views import View from djangorestframework.views import View