Reputation: 13590
I am relatively new to Django, and have experience with Rails. In Rails you usually don't have to tweak too much the routes (Django's urls.py
) because of the REST
convention of /controller/action/index
. So I thought of "importing" some of Rails' behaviour for my project so that I don't have to rewrite the urls.py
every time I add a new view.
This is my main urls.py
file
from django.conf.urls import patterns, include, url
from django.views.generic.simple import redirect_to
urlpatterns = patterns('',
url(r'^$', redirect_to, {'url': '/monitor/'}),
url(r'^monitor/', include('monitor.urls')),
)
In monitor/urls.py
, I have
from django.conf.urls import patterns, include, url
urlpatterns = patterns('monitor.views',
(r'^$', 'dispatcher'),
(r'^(?P<action>\w+)/(?P<id>.*$)', 'dispatcher'),
)
And my monitors.views.dispatcher
function looks like
def dispatcher(request, action=None, id=None):
if action == None:
action = "index"
try:
act_func = globals()[action]
except KeyError, e:
return HttpResponseNotFound("No %s action defined. Page not found." % (action))
return act_func(request, id)
I had quite a few problems with redirect
(see Understanding django.shortcuts.redirect) but this does not seem to be the source if these problems. Anyway it got me thinking and now I'm not quite sure if my dispatcher was a good idea to begin with.
I had also a discussion with one of my colleagues how was not very fond of it. He said that he felt that I've introduced a potential security risk. If anyone knows the structure of the code then you could exploit it. While his argument seems valid to me, in our environment it is rather unlikely that someone (beside ourselves) get to read our code.
Anyway, I'd like to know what people more experienced with Python and Django think about it.
Upvotes: 1
Views: 105
Reputation: 9262
I agree with your colleague. You should use urls.py
following the instructions in the documentation.
Firstly, on the perceived advantage:
So I thought of "importing" some of Rails' behaviour for my project so that I don't have to rewrite the
urls.py
every time I add a new view.
You don't ever have to "rewrite urls.py
"; you have to add a single line. This explicit-is-better-than-implicit approach runs right to the heart of Python, and if you start fighting it now you'll continue to run into similar problems.
Secondly, there is a security problem with your code.
Right off the bat, it's better to have URLs defined explicitly — read this take-down of Diaspora (intended as an open-source Facebook competitor in Rails) to get an idea of how automatic URL routing can contribute to gaping security holes.
Secondly, one wouldn't need to be able to see the source code to exploit the backdoor you have designed. globals()
doesn't just contain the local view functions, it contains all imported modules. It's dangerous to hope that an attacker can't find a damaging function (perhaps on one of your models, or in sys
or os
if you import those) that accepts two parameters.
Upvotes: 4