Werkzeug direcciones URL de asignación a las vistas (a través de punto final)

StackOverflow https://stackoverflow.com/questions/1796063

  •  22-09-2019
  •  | 
  •  

Pregunta

A partir usando werkzeug, intento trazar URL (desde un archivo urls.py) a puntos de vista (de una vistas de carpeta y luego en diferentes archivos para manejar diferentes tipos de vista), mis organización de carpetas se parece a lo siguiente:

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

mis urls.py archivos se parece a lo siguiente:

from werkzeug.routing import Map, Rule  

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

y, obviamente, tengo esa pieza en el archivo de puntos de vista / places.py:

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

La mayoría de los ejemplos Werkzeug muestran la utilización del decorador de exponer adjuntar direcciones URL a las vistas. Es práctico para una aplicación con 5 o 6 direcciones URL, pero puede convertirse en un infierno cuando tienes más ...

¿Hay una manera simple de correlacionar los URL directamente a los puntos de vista ???
Gracias.

¿Fue útil?

Solución

Este es un ejemplo simplificado:

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)

Otros consejos

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),
])

punto final puede ser cualquier cosa, incluyendo la función, por lo que sólo puede saltar la magia de importación del ejemplo de Denis

No estoy seguro de si se trata de manera preferida de abordar este problema (no he encontrado ningún ejemplo similar en werkzeug repo y todavía estoy jugando solamente con este lib), pero también es posible simplemente subclase Regla:

class CoolRule(Rule):

    def __init__(self, view, *args, **kwargs):
        self.view = view
        super(CoolRule, self).__init__(*args, **kwargs)

    def empty(self):
        """We need this method if we want to use 
           Submounts or Subdomain factories
        """
        defaults = dict(self.defaults) if self.defaults else None
        return CoolRule(self.view, self.rule, defaults, self.subdomain,
                        self.methods, self.build_only, self.endpoint, 
                        self.strict_slashes, self.redirect_to,
                        self.alias, self.host)


_url_map = Map([
    CoolRule(user.views.login, '/login', endpoint='user-login'),
    CoolRule(user.views.logout, '/logout', endpoint='user-logout'),
])

def dispatch(request):
    urls = _url_map.bind_to_environ(request.environ)
    rule, arguments = urls.match(return_rule=True)
    return rule.view(request, **arguments)

De esta manera se puede preservar la capa de abstracción de vista de nomenclatura y evitar extraña magia con 'cadena de importación'.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top