Linux E X P R E S

Facebook

Webové aplikace v Pythonu, 5. část

Jak už jsem zmínil, administrační modul není pro vaši aplikaci povinný, ale například u mého projektu NanoComment je výhodný. Nechtělo se mi vytvářet kód pro editaci nebo mazání příspěvků, pokud by ovšem někdo poslal nějaký nevhodný text, můžu záznam přes panel snadno smazat a nemusím se ani hlásit na server a provádět SQL dotazy.


Server ponechte spuštěný a jdeme na psaní kontrolerů a pohledů. Když otevřete soubor urls.py z hlavního adresáře projektu, spatříte jednoduché mapování URL adres na kontroléry, kterou uvádím ve výpisu.

Mapování adres
from django.conf.urls.defaults import *
from settings import myAPP_ROOT_DIR
urlpatterns = patterns('',
(r'^nc/', include('nanocomment.comments.urls')),
(r'^admin/', include('django.contrib.admin.urls.admin')),
(r'^styles/(?P.*)$', 'django.views.static.serve', \
{'document_root': myAPP_ROOT_DIR + '/media/styles'}),
)

Regulární výrazy jsou vstupní branou do projektu a udávají, jaké kontroléry budou prováděny. Vezměme to odspoda. Poslední řádek nastavuje pro všechny adresy začínající na styles/ vestavěný kontrolér static.serve, který jen načítá z daného adresáře soubory. Nic víc, to využijeme pro soubory se styly v CSS. Prostřední řádek aktivuje administrační panel, o kterém jsme se již bavili. Pro nás je nejzajímavější první řádek, který zpracování všech adres začínajících na nc/ deleguje na soubor comments/urls.py. Ten uvádím opět ve výpisu.

Mapování adres pro aplikaci comments
from django.conf.urls.defaults import *
urlpatterns = patterns('nanocomment.comments.views',
(r'^comments/(?P[\w\._-]+)/$', 'list'),
(r'^comments/(?P[\w\.-]+)/post/$', 'post'),
)

Zde je již situace jasnější. Adresy tvaru nc/comments/cokoli/ budou zpracovány funkcí list z modulu comments.views. To uprostřed je regulární výraz (akceptující písmena, číslice, tečka a podtržítko) doplněný o název proměnné, do které se tento kus adresy uloží. Druhý řádek pak mapuje podobnou adresu, ale končící na post/ a deleguje zpracování funkci jménem post.

Nyní vás asi zajímá, jak vypadají vlastní kontroléry. Jsou to obyčejné moduly v Pythonu, co jiného. V rámečku uvádím zkrácenou ukázku metody list (kompletní zdrojový kód najdete v souboru views.py).

Kontrolér comments.views
def list(request, article):
list = comments.get_list(article__exact=article)
list_len = len(list)
c = Context({
"article": article,
"comments": list })
return render_to_response("comments/list", c)

Metoda list kontroléru comments.views má za úkol získat seznam komentářů pro daný článek, vyrenderovat šablonu s výsledkem a poslat ji klientovi. Jméno článku je vloženo v proměnné article - viz regulární výraz výše. Nejprve je získán seznam instancí třídy Comment metodou get_list, poté je vytvořen jmenný prostor šablony (kontext), do kterého jsou vloženy potřebné proměnné a je vyrenderována šablona comments/list.html s daným kontextem.

Posledním článkem mozaiky jsou právě zmíněné šablony. Django má vlastní systém šablon, který je velmi promyšlený, snadný na použití, rychlý a rozšiřitelný. Disponuje několika desítkami příkazů (if, endif, for, endfor, block aj.) a systémem filtrů. Tyto entity se do šablony zapisují pomocí znaků {% %} a proměnné pak zdvojenými složenými závorkami {{ }}.

Šablony mají musejí mít standardně příponu html, ale můžete to změnit. Základním stavebním kamenem jsou bloky - můžete označovat kusy HTML názvy a v podřízených šablonách, které stojí v adresářové struktuře o úroveň níže, tyto bloky předefinovávat. Je to podobné jako přetěžování metod u potomků v OOP. V projektu NanoComment jsem vytvořil šablonu index.html a podšablonu comments/list.html. Šablona index.html definuje hlavní vzhled celé aplikace a bloky pojmenované title resp. content (obsah titulku resp. obsah stránky). Šablona comments/list.html (v rámečku) pak příkazem extends "dědí" z šablony index.html a získává tak její vzhled. Stačí tedy jen nastavit hodnoty bloků.

Ukázka šablony
{% extends "index" %}
{% block title %}
komentáře k {{ article }}
{% endblock %}
{% block content %}
{% if comments %} {% for c in comments %}
{{ c.body|escape|linebreaksbr}}
Napsal(a) {{ c.author|escape }} dne {{ c.time|date:"j. n. Y (H:i)" }}
{% endfor %} {% else %} Žádné komentáře. {% endif %}
{% endblock %}

K výpisu netřeba komentář. Proměnné article a comments jsou šabloně předány pomocí kontextu. Dobré je, že tento způsob psaní šablon nevyžaduje dodržovat pythonovské odsazení (blokové příkazy jsou v páru). Všimněte si také znaku | (pipe), kterým jsou realizovány zmíněné filtry. Například proměnnou c.body je nutné zbavit HTML značek (filtr escape) a následně převést konce řádků na HTML značku
(filtr linebreaksbr). Podobně se formátuje čas příspěvku. Inspirace v Bashi je zřejmá.

Za velmi dobrou vlastnost považuji nemožnost psaní kódu v šablonách. Neexistuje entita, pomocí které by programátor mohl vkládat příkazy Pythonu. Pohled musí být oddělen od kontroléru a veškerá data musejí být šabloně předána přes kontext.

Seznámili jsme se s útrobami ukázkové aplikace NanoComment, pokud jste ještě nezastavili vývojový server, přejděte na adresu localhost:8080/nc/comments/test123/ (lomítko na konci je nutné) a zkuste přidat komentář. Proti spam-botům je nutné před prvním komentářem vypočítat jednoduchý matematický příklad. Aplikaci můžete také vyzkoušet na domovské stránce NanoCommentu.

Cílem krátkého seriálu bylo představit možnosti webového programování v Pythonu s důrazem na framework Django. Snažil jsem se představit základní principy a vše to doplnit poznámkami na okraji o aplikačních serverech, které celou problematiku vhodně doplňují.

Popsaná aplikace NanoComment je dostupná pod licencí GNU GPL pro jakékoliv experimentování. Pokud byste ji výrazněji vylepšili, nebo třeba jen vytvořili jinou šablonu nebo CSS styl, pošlete mi SVN diff a já vše rád do projektu zahrnu.

Diskuze (0) Nahoru