django-reroute is a set of tools for simplifying your views, especially when you're implementing a REST API. django-reroute provides a drop-in replacement for django.conf.urls.defaults that supports HTTP verb dispatch so that your views don't become cluttered with if request.method == 'GET'
statements. It also provides a nifty set of view decorators for simplifying common tasks like rendering a template using a RequestContext and redirecting to a particular view after request processing.
Django 1.3 is now supported as of v1.1.1
Github: http://github.com/dnerdy/django-reroute
easy_install:
easy_install django-reroute
Source:
# Download the source and run python setup.py install
django-reroute is a drop-in replacement for django.conf.urls.defaults:
# Replace from django.conf.urls.defaults * # with from reroute import *
Although it's better to be explicit:
# Replace from django.conf.urls.defaults import handler404, handler500, patterns, url, include # with from reroute import handler404, handler500, patterns, url, include
verb_url patterns can match HTTP verbs in addition to regexes:
from reroute.verbs import verb_url urlpatterns = patterns('myapp.views', url('^regular$', 'regular_old_view'), verb_url('GET', '^restful$', 'restful_view') )
verb_url pattern regexes can be overloaded, enabling routing solely based on HTTP verb:
urlpatterns = patterns('myapp.views', verb_url('GET', '^restful$', 'restful_view'), verb_url('PUT', '^restful$', 'another_restful_view') )
Restful resource example:
paychecks = patterns('myapp.views.employees.paychecks', verb_url('GET', '^paychecks$', 'index_paychecks'), verb_url('POST', '^paychecks$', 'add_paycheck'), ) urlpatterns = patterns('myapp.views.employees', verb_url('GET', '^employees$', 'index_employees'), verb_url('POST', '^employees$', 'add_employee'), verb_url('GET', '^employees/(?P<employee_id>\d+)$', 'show_employee') verb_url('PUT', '^employees/(?P<employee_id>\d+)$', 'update_employee') verb_url('DELETE', '^employees/(?P<employee_id>\d+)$', 'delete_employee'), url('^employees/(?P<employee_id>\d+)/', include(paychecks)), )
Return a dictionary of values to add to the template context:
@render('template.html') def view(request): return {'title': 'This is the page title'} # The template is rendered using a RequestContext instance
If you need, return an HttpResponse and it will be used:
@render('template.html') def view(request): if special_case: return HttpResponse('This response will be used instead of rendering template.html') else: return {'title': 'This is the page title'}
Return a dictionary of values to use as reverse kwargs:
@redirect('other_view_name') def view(request): return {'view_kwarg': 42} # This is equivalent to: # return HttpResponseRedirect(reverse('other_view_name', kwargs={'view_kwarg': 42})) @render('other_tempate.html') def other_view(request, view_kwarg): return { 'title': 'This is the other view page title', 'message': 'Meaning of life? {0}'.format(view_kwarg) }
Again, if you return an HttpResponse it will be used:
@redirect('other_view_name') def view(request): if special_case: return HttpResponse('This response will be used instead of redirecting') else: return {'view_kwarg': 42}
Wrappers are like middleware that are applied to a selective set of urls. A wrapper is any callable that takes the arguments: view
, request
, *args
, **kwargs
:
import logging from reroute import reroute_patterns def wrapper_one(view, request, *args, **kwargs): logging.debug("wrapper one") return view(request, *args, **kwargs) def wrapper_two(view, request, *args, **kwargs): logging.debug("wrapper two") return view(request, *args, **kwargs) urlpatterns = reroute_patterns([wrapper_one, wrapper_two], 'myapp.views', verb_url('GET', '^restful$', 'restful_view'), verb_url('PUT', '^restful$', 'another_restful_view') )
You can even get fancy and create your own drop-in replacement for patterns:
from functools import partial patterns = partial(reroute_patterns, [wrapper_one, wrapper_two]) urlpatterns = patterns('myapp.views', verb_url('GET', '^restful$', 'restful_view'), verb_url('PUT', '^restful$', 'another_restful_view') )
- [NEW] Added support for Django 1.3
- [NEW] Added
render
andredirect
decorators toreroute.decorators
for simplifying common views tasks (namely rendering a template or redirecting to another view) - [FIXED] verb_url patterns are sporadically grouped incorrectly resulting in 405 responses. Python maintains a regex cache that is cleared after 100 entries, and verb_url patterns are group by regex object as opposed to the regex pattern. When the cache is cleared, regex objects with the same regex pattern are no longer equal.
- [FIXED] The PyPI package doesn't work with pip
- [NEW] Added support for the csrf_exempt decorator
- [FIXED] The incorrect default kwargs are used for verb_url patterns that have the same regex
django-reroute was written by Mark Sandstrom.