views:

34

answers:

2

In my Django project, my url.py module looks something like this:

urlpatterns = patterns('',
    (r'^$', 'web.views.home.index'),
    (r'^home/index', 'web.views.home.index'),
    (r'^home/login', 'web.views.home.login'),
    (r'^home/logout', 'web.views.home.logout'),
    (r'^home/register', 'web.views.home.register'),
)

Is there a way to simplify this so that I don't need an entry for every method in my view? Something like this would be nice:

urlpatterns = patterns('',
    (r'^$', 'web.views.home.index'),
    (r'^home/(?<method_name>.*)', 'web.views.home.(?P=method_name)'),
)

UPDATE

Now that I know at least one way to do this, is this sort of thing recommended? Or is there a good reason to explicitly create a mapping for each individual method?

+2  A: 

May be something like that:

import web.views.home as views_list
urlpatterns = patterns('',
    (r'^$', 'web.views.home.index'),
    *[(r'^home/%s' % i, 'web.views.home.%s' % i) for i in dir(views_list)]
)
Riateche
Nice! I suppose to be secure I'd need to check for some sort of custom decorator (@public or @web_method or something).
MikeWyatt
`dir(amodule)` will contain special names (with double underscore before and after) such as `__file__`, `__name__` etc -- you definitely want to avoid _those_!-). A simple decorator can build up the list of interesting views explicitly -- recommended.
Alex Martelli
+2  A: 

You could use a class-based view with a dispatcher method:

class MyView(object):
    def __call__(self, method_name):
        if hasattr(self, method_name):
            return getattr(self, method_name)()


    def index(self):
        ...etc...

and your urls.py would look like this:

from web.views import MyView
urlpatterns = patterns('',
    (r'^$', 'web.views.home.index'),
    (r'^home/(?<method_name>.*)', MyView()),
)
Daniel Roseman