Django Convention Over Configuration Urls Routing
Convention Over Configuration Urls Routing and Templates Rendering for your Django Projects. (Yeah, forget about urls.py!)
~$ python setup.py install
Run test suite
~$ sh run_tests.sh
- python 2.7
- python 3.2+ (Since version 0.2.0)
How it works
django_conventions uses introspection the infer your views files and classes (at this moment it just works with django class based views). In order to start using it you just have to open your urls.py file (this will be the first and last time you open it) and add the following code:
from django.conf.urls import patterns, include, url from django_conventions import UrlsManager # You have to specify your views module import my_app.views as root urlpatterns = patterns('', # Write your regular urls here. django_conventions enables you to work with both your regular urls.py kind of routing and the convention over configuration routing. ) # Here is where the magic flows UrlsManager(urlpatterns, root)
In the code above root is the directory module of your views. django_conventions will look for all the files inside that directory and search for classes that inherit from django.views.generic.base.View or any of its subclasses (django.views.generic.base.TemplateView, django.views.generic.base.RedirectView, etc). This is done when you instantiate the UrlsManager class inside urls.py.
Convention based routing and rendering
The urls for your views classes will be generated by just using its name (without the "View" suffix) and the name of the file where they are. For instance, a view class called MainView inside index.py will be automatically routed to ^index/main/$. Magic, uh?, but that's not all.
The render_to_response method will automatically render the template called main.html inside the index directory under your templates folder.
from django.views.generic import TemplateView class MainView(TemplateView): """ The url for this view will be ^index/main/$ The template rendered will be main.html under the index directory. """ pass
from django.views.generic import TemplateView class LoginView(TemplateView): """ The url for this view will be ^user/login/$ The template rendered will be login.html under the user directory. """ def render_to_response(self, context): # Write your regular view code here return MainView.render_to_response(self, context)
Overriding the defaults
Conventions are amazing! But what's when you need to override them to get a different url or to render a different template? Are you thinking on going back to urls.py? Luckily there's no need to do it!
Just define a url class attribute on your classes to route it to the url you want (fully django regular expressions for defining urls is supported).
In the same way, just define a template_name class attribute to render the template you need.
from django.views.generic import TemplateView class GetClientView(TemplateView): # Use regular expression just like you used to do in urls.py url = r"^client/(?P<client_id>\d)/$" template_name = "business/client.html" """ The url for this view will be ^client/(?P<client_id>\d)/$ (the default ^/customers/getclient/$ was overwritten by the url attribute) The template rendered will be client.html under the business directory (the default customers/getclient.html was overwritten by the template_name attribute). """ pass
Multiple Urls Mapping
Some times you want two or more views to be routed to the same url. In that case you can make the url class attribute a list of urls.
from django.views.generic import TemplateView class CustomersView(TemplateView): # You can pass a list of urls to this attribute url = [r"^business/customers/$", r"^business/buyers/$", #...] """ The urls for this view will be ^business/customers/$, ^business/buyers/$ and all the ones that you add in the url attribute list. """ pass