views:

339

answers:

2

Starting using werkzeug, i try to map urls (from a file urls.py) to views (from a folder views and then in different files to manage differents kinds of view), my folder organisation looks like that :

myapp/
- - - application.py
- - - urls.py
- - - views/
- - - - - - __init__.py
- - - - - - common.py
- - - - - - places.py
- - - - - - ...

my urls.py files looks like that:

from werkzeug.routing import Map, Rule  

url_map = Map([  
Rule('/places', endpoint='places.overview')  
])

and obviously i got that piece in the views/places.py file :

def overview(request):
    mycode...
    render_template('places.html', extra...)

Most of werkzeug examples show the utilisation of the decorator expose to attach urls to views. It's practical for an app with 5 or 6 urls but can become a hell when you got more...

Is there a simple way to map the urls directly to the views???
Thanks.

+2  A: 

Here is a simplified example:

import views

def app(environ, start_response):
    urls = url_map.bind_to_environ(environ)
    request = Request(environ)
    endpoint, params = urls.match()
    names = endpoint.split('.')
    view = views
    for name in names:
        if not hasattr(view, name):
            __import__(view.__name__, None, None, [name])
        view = getattr(view, name)
    try:
        response = view(request)
    except werkzeug.exceptions.HTTPException, exc:
        response = exc
    return response(environ, start_response)
Denis Otkidach
thank you i used your solution and it works well.
Jérôme Pigeot
+2  A: 
import letters # our views module

url_map = Map([
    Rule('/letters', endpoint=letters.index),
    Rule('/letters/<int:item_id>', endpoint=letters.item),
    Rule('/letters/<string:section_slug>', endpoint=letters.index),
    Rule('/letters/<string:section_slug>/<int:item_id>',
         endpoint=letters.item),
])

endpoint can be anything, including function, so you can just skip import magic from Denis's example

barbuza
yes that can be usefull but then you need to import all the views in the urls.py files and in templates to use "url_for" for example. Thanks
Jérôme Pigeot