From ca9465f11e3310b7b1e18cd893e96b69963f68c9 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 21 Feb 2012 20:47:55 +0000 Subject: [PATCH] reverse gets it's own module --- djangorestframework/compat.py | 8 ++++++++ djangorestframework/resources.py | 3 ++- djangorestframework/reverse.py | 23 +++++++++++++++++++++++ djangorestframework/tests/reverse.py | 25 +++++++++++++++---------- djangorestframework/utils/__init__.py | 20 +------------------- docs/howto/reverse.rst | 18 +++++------------- docs/library/reverse.rst | 5 +++++ docs/library/utils.rst | 5 ----- examples/blogpost/resources.py | 2 +- examples/blogpost/tests.py | 2 +- examples/mixin/urls.py | 2 +- examples/objectstore/views.py | 2 +- examples/permissionsexample/views.py | 2 +- examples/pygments_api/views.py | 2 +- examples/resourceexample/views.py | 2 +- examples/sandbox/views.py | 2 +- 16 files changed, 67 insertions(+), 56 deletions(-) create mode 100644 djangorestframework/reverse.py create mode 100644 docs/library/reverse.rst delete mode 100644 docs/library/utils.rst diff --git a/djangorestframework/compat.py b/djangorestframework/compat.py index 7690316c9..b818b4462 100644 --- a/djangorestframework/compat.py +++ b/djangorestframework/compat.py @@ -457,3 +457,11 @@ except ImportError: # python < 2.7 return decorator 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) diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py index 5e126defe..2b84ee09d 100644 --- a/djangorestframework/resources.py +++ b/djangorestframework/resources.py @@ -3,8 +3,9 @@ from django.core.urlresolvers import get_urlconf, get_resolver, NoReverseMatch from django.db import models from djangorestframework.response import ErrorResponse +from djangorestframework.reverse import reverse from djangorestframework.serializer import Serializer, _SkipField -from djangorestframework.utils import as_tuple, reverse +from djangorestframework.utils import as_tuple class BaseResource(Serializer): diff --git a/djangorestframework/reverse.py b/djangorestframework/reverse.py new file mode 100644 index 000000000..ad06f9664 --- /dev/null +++ b/djangorestframework/reverse.py @@ -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) diff --git a/djangorestframework/tests/reverse.py b/djangorestframework/tests/reverse.py index 3ac04d8c0..9c0aee796 100644 --- a/djangorestframework/tests/reverse.py +++ b/djangorestframework/tests/reverse.py @@ -2,27 +2,32 @@ from django.conf.urls.defaults import patterns, url from django.test import TestCase 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 -class MockView(View): - """Mock resource which simply returns a URL, so that we can ensure that reversed URLs are fully qualified""" - permissions = () +class MyView(View): + """ + Mock resource which simply returns a URL, so that we can ensure + that reversed URLs are fully qualified. + """ + renderers = (JSONRenderer, ) def get(self, request): - return reverse('another', request) + return reverse('myview', request) urlpatterns = patterns('', - url(r'^$', MockView.as_view()), - url(r'^another$', MockView.as_view(), name='another'), + url(r'^myview$', MyView.as_view(), name='myview'), ) class ReverseTests(TestCase): - """Tests for """ + """ + Tests for fully qualifed URLs when using `reverse`. + """ urls = 'djangorestframework.tests.reverse' def test_reversed_urls_are_fully_qualified(self): - response = self.client.get('/') - self.assertEqual(json.loads(response.content), 'http://testserver/another') + response = self.client.get('/myview') + self.assertEqual(json.loads(response.content), 'http://testserver/myview') diff --git a/djangorestframework/utils/__init__.py b/djangorestframework/utils/__init__.py index fc8bae924..537d42523 100644 --- a/djangorestframework/utils/__init__.py +++ b/djangorestframework/utils/__init__.py @@ -1,7 +1,7 @@ import django from django.utils.encoding import smart_unicode 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 djangorestframework.compat import StringIO @@ -174,21 +174,3 @@ class XMLRenderer(): def 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)) diff --git a/docs/howto/reverse.rst b/docs/howto/reverse.rst index e4efbbcab..73b8fa4df 100644 --- a/docs/howto/reverse.rst +++ b/docs/howto/reverse.rst @@ -1,12 +1,6 @@ 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". 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, ...) ------------------------------- -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 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, ...) ------------------------------------ -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 - -.. [1] https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse -.. [2] https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-lazy +.. _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 diff --git a/docs/library/reverse.rst b/docs/library/reverse.rst new file mode 100644 index 000000000..a2c29c488 --- /dev/null +++ b/docs/library/reverse.rst @@ -0,0 +1,5 @@ +:mod:`reverse` +================ + +.. automodule:: reverse + :members: diff --git a/docs/library/utils.rst b/docs/library/utils.rst deleted file mode 100644 index 653f24fde..000000000 --- a/docs/library/utils.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`utils` -============== - -.. automodule:: utils - :members: diff --git a/examples/blogpost/resources.py b/examples/blogpost/resources.py index d4e0594d8..d11c5615c 100644 --- a/examples/blogpost/resources.py +++ b/examples/blogpost/resources.py @@ -1,5 +1,5 @@ from djangorestframework.resources import ModelResource -from djangorestframework.utils import reverse +from djangorestframework.reverse import reverse from blogpost.models import BlogPost, Comment diff --git a/examples/blogpost/tests.py b/examples/blogpost/tests.py index 9f72e6862..23f1ac21d 100644 --- a/examples/blogpost/tests.py +++ b/examples/blogpost/tests.py @@ -5,7 +5,7 @@ from django.test import TestCase from django.utils import simplejson as json from djangorestframework.compat import RequestFactory -from djangorestframework.utils import reverse +from djangorestframework.reverse import reverse from djangorestframework.views import InstanceModelView, ListOrCreateModelView from blogpost import models, urls diff --git a/examples/mixin/urls.py b/examples/mixin/urls.py index 1f8c93b2c..9652cfda4 100644 --- a/examples/mixin/urls.py +++ b/examples/mixin/urls.py @@ -2,7 +2,7 @@ from djangorestframework.compat import View # Use Django 1.3's django.views.gen from djangorestframework.mixins import ResponseMixin from djangorestframework.renderers import DEFAULT_RENDERERS from djangorestframework.response import Response -from djangorestframework.utils import reverse +from djangorestframework.reverse import reverse from django.conf.urls.defaults import patterns, url diff --git a/examples/objectstore/views.py b/examples/objectstore/views.py index 61d51b1be..dd7114820 100644 --- a/examples/objectstore/views.py +++ b/examples/objectstore/views.py @@ -1,6 +1,6 @@ from django.conf import settings -from djangorestframework.utils import reverse +from djangorestframework.reverse import reverse from djangorestframework.views import View from djangorestframework.response import Response from djangorestframework import status diff --git a/examples/permissionsexample/views.py b/examples/permissionsexample/views.py index 83ef0fd9a..b0c1f02ef 100644 --- a/examples/permissionsexample/views.py +++ b/examples/permissionsexample/views.py @@ -1,6 +1,6 @@ from djangorestframework.views import View from djangorestframework.permissions import PerUserThrottling, IsAuthenticated -from djangorestframework.utils import reverse +from djangorestframework.reverse import reverse class PermissionsExampleView(View): diff --git a/examples/pygments_api/views.py b/examples/pygments_api/views.py index 01710bd50..b53966813 100644 --- a/examples/pygments_api/views.py +++ b/examples/pygments_api/views.py @@ -4,7 +4,7 @@ from django.conf import settings from djangorestframework.resources import FormResource from djangorestframework.response import Response from djangorestframework.renderers import BaseRenderer -from djangorestframework.utils import reverse +from djangorestframework.reverse import reverse from djangorestframework.views import View from djangorestframework import status diff --git a/examples/resourceexample/views.py b/examples/resourceexample/views.py index 2f623c39a..1b5b8e9c3 100644 --- a/examples/resourceexample/views.py +++ b/examples/resourceexample/views.py @@ -1,4 +1,4 @@ -from djangorestframework.utils import reverse +from djangorestframework.reverse import reverse from djangorestframework.views import View from djangorestframework.response import Response from djangorestframework import status diff --git a/examples/sandbox/views.py b/examples/sandbox/views.py index 3872b5037..78e00f463 100644 --- a/examples/sandbox/views.py +++ b/examples/sandbox/views.py @@ -1,6 +1,6 @@ """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