Píšeme views

View function” nebo zkráceně view je jednoduchá Pythoní funkce, která zpracuje žádost z prohlížeče (web request) a vrátí mu odpověď (web response). Ta může být ve formě HTML dokumentu, přesměrování, chyby 404, XML dokumentu, obrázku … prostě cokoliv. Kód view může být umístěn kdekoliv na “Python path”. A toť vše – žádná další kouzla nejsou třeba. Jelikož kód obsahující view někam dát musíme, je nejlepší ho spolu s ostatními views vložit do souboru views.py, který se nachází v kořenovém adresáři projektu nebo aplikace.

Jednoduché view

Pojďme se podívat na jednoduchý příklad – view, které vrací aktuální datum a čas ve formě HTML stránky:

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>Prave je %s.</body></html>" % now
    return HttpResponse(html)

Pojďme si kód rozebrat:

  • Nejdříve importujeme třídu HttpResponse z modulu django.http a k tomu importujeme i Python knihovnu datetime.

  • Jako další si nadefinujeme funkci current_datetime. Ta je nyní view funkcí (“view function”). Každá view funkce přebírá v prvním parametru objekt HttpRequest, který je většinou pojmenován request.

    Svojí view funkci si můžete pojmenovat jakkoliv. Nemusí mít nějaké speciální jméno, aby Django rozpoznalo. V našem ukázkovém kódu ji máme pojmenovanou current_datetime (takže nás hned trkne co dělá).

  • View nám poté vrací objekt HttpResponse obsahující vygenerovanou odpověď. Každá view funkce je zodpovědná za vrácení objektu HttpResponse. (Jsou zde nějaké výjimky, k těm se dostaneme později)

Časové pásmo Djanga

Ve výchozí konfiguraci je Django nastaveno na časové pásmo America/Chicago. Potomkům praotce Čecha doporučujeme změnit proměnnou TIME_ZONE na hodnotu Europe/Prague.

Přiřazování URL adres k views

Krátké opáčko: naše view funkce vrací HTML stránku s aktuálním časem. Pokud jej chceme zobrazit po zadání určité URL adresy, musíme vytvořit URLconf; pro instrukce se podívejte na URL dispatcher.

Vracení chyb

Vracení chybových kódů HTTP je v Djangu snadné. Všechny kódy jsou odvozeny z třídy HttpResponse (jejich kompletní seznam naleznete v dokumentaci request/response). Stačí když namísto HttpResponse vrátíte některou z definovaných podtříd HttpResponse, a chybové hlášení je na světě:

def muj_view(request):
    # ...
    if foo:
        return HttpResponseNotFound('<h1>Stranka neexistuje</h1>')
    else:
        return HttpResponse('<h1>Stranka existuje</h1>')

HTTP specifikace definuje velké množství stavů a Django přináší definice pouze těch nejobvyklejších. Pokud ve vaší aplikaci budete potřebovat vracet jiný typ chyby, můžete poslat stavový kód HTTP přímo přes konstuktor třídy HttpResponse:

def muj_view(request):
    # ...

    # Vratime "vytvoreny" stavovy kod (201).
    return HttpResponse(status=201)

Výjimka Http404

class django.http.Http404

Při vrácení chyby HttpResponseNotFound musíme dodat i HTML obsah chybové stránky:

return HttpResponseNotFound('<h1>Stranka nenalezena</h1>')

Pro větší pohodlí (a taky protože je dobré generovat pro chybu 404 vždy stejnou stránku) nám Django poskytuje výjimku Http404. Jakmile ji kdekoliv ve view funkci vyvoláme, Django ji odchytí a vrátí standardní chybovou stránku pro vaší aplikaci včetně chybového HTTP kódu 404.

Názorné využití:

from django.http import Http404

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404
    return render_to_response('polls/detail.html', {'poll': p})

Pokud chcete výjimku Http404 využít naplno, je vhodné umístit do adresáře s šablonami soubor 404.html, jehož obsah se uživatelům vaší aplikace zobrazí vždy, pokud vyjímka nastane.

Přizpůsobení chybových view

View 404 (stránka nenalezena)

Po vyvolání výjimky Http404 Django zavolá speciální view, které načte a vykreslí šablonu 404.html (viz django.views.defaults.page_not_found).

To znamená, že musíme vytvořit soubor 404.html v kořenovém adresáři šablon. Tato šablona bude využita pro všechny chyby 404. Defaultní view pro 404 navíc do kontextu šablony pošle proměnnou request_path s URL adresou na které chyba nastala.

View page_not_found by mělo být dostatečné pro 99% webových aplikacích, ale kdyby jste ho z nějakého důvodu nechtěli použít, stačí ve vašem URLconf nadefinovat proměnnou handler404:

handler404 = 'mysite.views.my_custom_404_view'

Aby jste věděli: fachá to tak, že Django se nejprve podívá do URLconfu, a teprve pokud tam nenajde handler404, použije výchozí django.views.defaults.page_not_found.

Čtyři věci ohledně view 404:

  • View 404 je voláno i v případech, kdy Django v definici URLconf nenajde pravidlo pro požadovanou stránku.
  • Když si nenadefinujete své vlastní view pro 404 — a používáte základní view (což je doporučeno) — stále máte jednu povinnost: musíte vytvořit soubor 404.html v rootu šablonového adresáře.
  • Do view 404 se posílá objekt RequestContext a tudíž bude mít přístup k proměnným definovaným v TEMPLATE_CONTEXT_PROCESSORS (např. MEDIA_URL apod.).
  • Pokud je DEBUG nastaven na True (v settings.py), tak se view 404 nikdy nezavolá, a místo toho bude zobrazen URLconf společně s hrstkou debug informací.

View 500 (server error)

Pokud během chodu vašeho view dojde k runtime chybě, zachová se Django podobně jako v případě chyb 404 — zavolá view django.views.defaults.server_error a to načte a zobrazí šablonu 500.html.

V adresáři s šablonami musíte vytvořit soubor 500.html. Tato šablona bude využívána pokaždé, když ve vaší aplikaci na serveru dojde k nějaké chybě. Defaultní view 500 neposílá do šablony žádné proměnnné, aby se zabránilo dalším případným chybám.

View server_error by mělo stačit pro 99% webových aplikacích, ale kdyby jste ho nechtěli z nějakého důvodu použít, stačí nadefinovat proměnnou handler500 ve vašem URLconf:

handler500 = 'mysite.views.my_custom_error_view'

Aby jste věděli: fachá to tak, že Django se nejprve podívá do URLconfu, a teprve pokud tam nenajde handler500, použije výchozí django.views.defaults.server_error.

Dvě věci ohledně view 500:

  • Když si nenadefinujete své vlastní view 500 — a používáte základní view (což je doporučeno) — stále máte jednu povinnost: musíte vytvořit soubor 500.html v rootu šablonového adresáře.
  • Pokud je DEBUG nastaven na True (v settings.py), tak se view 500 nikdy nezavolá, a namísto toho bude zobrazen traceback s debug informacemi o tom, kde a jaká chyba nastala.