Poprzedni wpis (Mniej limitów na Google AppEngine) | Następny wpis (Zrób swoje własne Django, odc. 2 - procesory kontekstu)

Zrób swoje własne Django, odc. 1 - middleware

Żartuję, Django jest na tyle dobre, żeby nie musieć go robić samemu. Chodzi mi raczej o sytuację, kiedy chce się mieć tyle Django, ile trzeba i ani trochę więcej (na przykład dlatego, że z całego oryginalnego Django wykorzystuje się tylko parę komponentów, bo na więcej nie pozwala AppEngine). Z pomocą przychodzi Werkzeug, Beaker i Jinja2 i parę innych bibliotek. Oprócz oczywistego zysku, jakim jest odchudzenie narzędziówki o kilka cennych setek plików, można zyskać bezcenną wiedzę, jak działa Django (im więcej wiem, tym większym podziwem darzę core devs, bo Django okazuje się jeszcze lepsze, niż wygląda na pierwszy rzut oka).

W paru kolejnych odcinkach opiszę rzeczy, które uznawałem za bardzo użyteczne w Django i zaimplementowałem sobie jako uzupełnienie narzędziówki (inna rzecz, że niełatwo jest się wyrzec niektórych przyzwyczajeń).

Middleware

Nie chodzi mi o middleware w rozumieniu WSGI, lecz takie, jak w Django — metody zwykłych klas, które są wywoływane z ustalonymi argumentami w określonych momentach przetwarzania żądania i odpowiedzi. Niespodzianka, Werkzeug ma już coś takiego! Nazywa się to Processor i klasa, która znajduje się w module werkzeug.contrib.kickstart pokazuje, jak powinien wyglądać kompletny interfejs takiej klasy i sygnatury jej metod. Leniwi mogą sobie z tej klasy po prostu odziedziczyć...

Pozostaje jedna rzecz, czyli podłączenie tego cuda do naszej aplikacji WSGI. Poniżej fragment mojej metody __call__() z klasy reprezentującej aplikację WSGI. Podłączam w niej tylko jeden rodzaj middleware (są jeszcze 3 inne możliwe).

for item in getattr(settings, 'MIDDLEWARES', []):
    try:
        klass = import_string(item)
        middleware = klass()
        response = middleware.process_request(request)
    except (ImportError, AttributeError):
        pass
    if response is not None:
        break
if response is None:
    local.url_adapter = adapter = url_map.bind_to_environ(environ)
    try:
        endpoint, values = adapter.match()
        handler = import_string(endpoint)
        response = handler(request, **values)
    except HTTPException, e:
        response = e

Inny sposób na podłączenie do kodu aplikacji WSGI można znaleźć na wiki Werkzeug — jak zwykle pełna wolność wyboru metody (oczywiście, działa dobrze w każdym przypadku).

W następnym odcinku

A w następnym odcinku okaże się, jak zrobić procesory kontekstu (context processors) takie jak w Django, a nawet lepsze. Tym razem w użyciu będzie zarówno Werkzeug jak i Jinja.

Komentarze (2)

#1 riklaunim skomentował(-a) 14 lutego 2009 o 23:26

Czy to takie "im mniej znane tym fajniejsze" ? Jeszcze trochę, a z web.py będą robić "Django" ;)

#2 jarek skomentował(-a) 15 lutego 2009 o 11:07

Nie wiem, czy "mniej znane". Werkzeug wydaje się całkiem popularny (szczególnie jego debugger).

Skomentujesz?

* 


* 


* oznacza pole wymagane