Mrkněme se na Django

Django bylo vyvinuto v novinářském prostředí, pro které bylo důležité, aby úkony spojené s webem byly prováděny rychle a jednoduše. Na této stránce vám bude demonstrováno nasazení Djanga při realizaci jednoduché, databází řízené webové aplikace.

Cílem tohoto dokumentu je poskytnout úměrné množství informací, s pomocí kterých dokážete pochopit, jak Django funguje. Až budete připraveni začít svůj vlastní projekt, můžete přejít k demonstrační aplikaci, nebo se začíst do detailnější dokumentace.

Navrhněte svůj model

I když vaše aplikace může pracovat i bez použití databáze, Django přichází se svým objektově-relačním mapovačem, který je zprostředkovatelem mezi datovým modelem (definovaným jako třída Pythonu) a relační databází.

Syntaxe datového modelu nabízí spoustu způsobů, jak modely reprezentovat. Zde je rychlý příklad:

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)

    def __unicode__(self):
        return self.full_name

class Article(models.Model):
    pub_date = models.DateTimeField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)

    def __unicode__(self):
        return self.headline

Nainstalujte jej

Spusťte následující příkaz. Django s jeho pomocí automaticky vytvoří databázové tabulky:

manage.py syncdb

Příkaz syncdb projde všechny dostupné modely a vytvoří pro ně tabulky v databázi (pokud ještě neexistují).

Užívejte si API rozhraní

Tak. Teď, když máme definovaný model, a vytvořeny všechny důležité tabulky v databázi, můžeme se pustit do objevování rozsáhlého Python API pro přístup k uloženým datům. API je vytvářeno za chodu, není třeba pro něj generovat žádný kód:

>>> from mysite.models import Reporter, Article

# V systemu jeste nejsou zadni novinari.
>>> Reporter.objects.all()
[]

# Vytvorime prvniho novinare.
>>> r = Reporter(full_name='John Smith')

# Ulozime objekt do databaze. Příkaz save() musime volat explicitne.
>>> r.save()

# Ted ma ID.
>>> r.id
1

# A novinar uz je v databazi.
>>> Reporter.objects.all()
[<Reporter: John Smith>]

# Pole modelu jsou reprezentovana jako atributy Python objektu.
>>> r.full_name
'John Smith'

# Django nabizi rozsahle API pro dotazovani databaze.
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__startswith='John')
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains='mith')
<Reporter: John Smith>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Reporter matching query does not exist.

# Vytvorime clanek.
>>> from datetime import datetime
>>> a = Article(pub_date=datetime.now(), headline='Django is cool',
...     content='Yeah.', reporter=r)
>>> a.save()

# Clanek je v databazi.
>>> Article.objects.all()
[<Article: Django is cool>]

# Objekty clanku maji pristup pres API k souvisejicim novinarum.
>>> r = a.reporter
>>> r.full_name
'John Smith'

# A naopak: objekty novinaru maji pres API pristup k clankum.
>>> r.article_set.all()
[<Article: Django is cool>]

# API sleduje relace mezi objekty, nezbytne spojovani tabulek (JOINy)
# provadi efektivne za vas.
# Tento prikaz najde vsechny clanky novinare, jehoz jmeno zacina na "John".
>>> Article.objects.filter(reporter__full_name__startswith="John")
[<Article: Django is cool>]

# Upravime objekt zmenou jeho atributu a pak zavolame save().
>>> r.full_name = 'Billy Goat'
>>> r.save()

# Objekt smazeme pouzitim delete().
>>> r.delete()

Dynamické administrační rozhraní: není to jenom lešení (scaffolding) — je to celý dům

Jakmile máte své modely navrženy, Django pro ně může automaticky vytvořit profesionální administrační rozhraní připravené k nasazení na produkční server. Na webových stránkách, které jsou přístupné pouze autorizovaným uživatelům, budete schopni přidávat, upravovat a mazat definované objekty. Nasazení administrace je velmi jednoduché:

# V souboru models.py...

from django.db import models

class Article(models.Model):
    pub_date = models.DateTimeField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)


# V souboru admin.py ve stejnem adresari...

import models
from django.contrib import admin

admin.site.register(models.Article)

Filozofie administračního rozhraní spočívá v tom, že web je upravován zaměstnanci, klientem, nebo možná přímo vámi — a vy se nechcete zdržovat s vytvářením rozhraní pro správu jeho obsahu.

Jeden z typických přístupů:

  • co nejdříve vytvořit modely a rozjet administrační rozhraní
  • začít web plnit daty (ze strany zaměstnanců či klientů)

A zatím co se nalévají další a další data, vy se začínáte věnovat způsobu, jakým budete data navštěvníkům webu prezentovat.

Vytvořte URL adresy

Čisté a elegantní URL adresy jsou důležitý detail kvalitní webové aplikace. Django takovýto návrh adres podporuje. S ohavnostmi typu .php nebo .asp se nadobro rozlučte.

URL adresy se definují v Python modulu URLconf. V něm se provede namapování URL šablon na Python callback funkce. URLconf také odděluje adresy a kód vaší aplikace.

Takhle nějak by mohl vypadat URLconf pro příklad s Reporter/Article uvedený výše:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^articles/(\d{4})/$', 'mysite.views.year_archive'),
    (r'^articles/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'),
    (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'),
)

Tento kód mapuje URL adresy ve formě regulárních výrazů na Python callback funkce (pohledy, z anglického “views”). Regulární výrazy používají závorky pro “zachycení” hodnot z URL adresy. Když si uživatel vyžádá stránku, Django projde každý regulární výraz v zadaném pořadí, a zastaví se na prvním, který se shoduje s požadovanou adresou. (Pokud se žádná neshoduje, Django volá speciální pohled 404.) Celý tento proces je velmi rychlý, protože regulární výrazy jsou zkompilovány při prvním spustění aplikace.

Když se jeden z regulárních výrazů shoduje s URL, Django naimportuje a spustí zadaný pohled (view), což není nic jiného, než jednoduchá Python funkce. Každému pohledu je předán request objekt — obsahující metadata požadavku — a hodnoty zachycené ve výrazu.

Např. pokud si uživatel vyžádá URL “/articles/2005/05/39323/”, Django zavolá funkci mysite.views.article_detail(request, ‘2005’, ‘05’, ‘39323’).

Napište své pohledy (views)

Každý z pohledů je zodpovědný za provedení jedné ze dvou věcí: buďto vrátí objekt HttpResponse, který obsahuje samotný obsah vyžádané stránky, nebo vyvolá výjimku jako je např. Http404. Zbytek je na vás.

Obecný postup je takový, že pohled vytáhne data podle dodaných parametrů, načte šablonu a naplní ji daty. Ukázkový pohled year_archive z příkladu výše:

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})

Tento příklad používá šablonovací systém Djanga, který obsahuje dostatek silných vlastností, ale přitom se snaží zůstat srozumitelný i pro neprogramátory.

Vytvořte šablony

Kód uvedený výše načte šablonu news/year_archive.html.

Django se pokusí šablonu nalézt v některém ze zadaných adresářů (definovaných v souboru settings.py). Pokud není nalezena v prvním adresáři, hledá se ve druhém, atd. Tímto způsobem je možné efektivně snížit nadbytečnost mezi šablonami.

Řekněme, že byla nalezena šablona news/article_detail.html. Takhle nějak by mohla vypadat:

{% extends "base.html" %}

{% block title %}Clanky za rok {{ year }}{% endblock %}

{% block content %}
<h1>Clanky za rok {{ year }}</h1>

{% for article in article_list %}
<p>{{ article.headline }}</p>
<p>Autor {{ article.reporter.full_name }}</p>
<p>Publikovano dne {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}

Proměnné jsou uzavřeny do dvojitých složených závorek. Výraz {{ article.headline }} znamená: “Vypiš hodnotu atributu headline objektu article”. Tečky ve výrazu ale neslouží pouze pro specifikování atributů: s jejich pomocí můžeme podle klíče vytahovat hodnoty ze slovníku, adresovat prvky seznamu nebo volat funkce.

Poznámka: {{ article.pub_date|date:”F j, Y” }} používá Unixovskou “rouru” (znak “|”). V Djangu tento výraz označujeme jako “filtr”. V naší ukázce filtr date formátuje Python objekt datetime do zadaného tvaru (je to podobné jako v PHP funkci date; ano, i v PHP je plno dobrých myšlenek).

Můžete dát za sebe tolik filtrů, kolik chcete. Můžete psát vlastní filtry. Můžete napsat vlastní šablonové tagy, které spustí libovolný Python kód.

Django využívá koncept “šablonové dědičnosti”: k tomuto účelu existuje tag {% extends “base.html” %}. Jeho funkce by se dala popsat takto: “Nejprve načti šablonu s názvem ‘base’, která má nadefinovanou skupinu bloků, a tyto bloky naplň následujícími bloky.” Tímto způsobem dramaticky snížíte zmatek v šablonách: každá šablona definuje pouze to, co je pro ni specifické.

Příklad, jak by “base.html” mohl vypadat:

<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="sitelogo.gif" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>

Zjednodušeně řečeno, tato šablona vytváří vzhled stránky, a nabízí “díry” pro naplnění podřazenou šablonu. Pokud budete chtít změnit design celého webu, stačí upravit jediný soubor — základní šablonu.

Tento koncept umožňuje vytvářet různé verze webu, za použití stejných podřazených šablon. Tvůrci Djanga tuto funkci využili při vytvoření zcela odlišné varianty webu pro mobilní telefony a při tom opět stačilo změnit pouze základní šablonu.

Poznámka: Pokud upřednostňujete jiný šablonovací systém, nemusíte šablony Djanga používat. Ze stejného důvodu nemusíte používat ani poskytované databázové API. Můžete využít jinou databázovou vrstvu, můžete číst XML soubory, můžete načítat soubory z disku nebo cokoli jiného. Každá část Djanga — modely, šablony, pohledy — je od ostatních oddělena.

Tohle je jen začátek

Právě jste se seznámili se základními vlastnostmi frameworku. Django vám ale nabízí mnohem víc, např.:

  • Cache framework integrovaný s memcached nebo jinými backendy.
  • Syndikační framework, který pro vytvoření RSS nebo Atom kanálů potřebuje nadefinovat pouze jednu malou Python třídu.
  • Kopu dalších funkcí do automaticky generovaného administračního rozhraní — tento přehled ukázal pouze to nejdůležitější.

Co teď? Stáhněte si Django, podívejte se na ukázkovou aplikaci a připojte se do komunity. Děkujeme za váš zájem!