Django: Nastavení projektu a první pokusy

Dnes si projdeme nastavení vytvořeného projektu a vyzkoušíme si rozběhat svou první aplikaci. K tomu budeme potřebovat přidat položku do seznamu URL, nějaký jednoduchý pohled a šablonu.
Seriál: Hrajeme si s Djangem (16 dílů)
- Django: Úvod a instalace 14. 8. 2009
- Django: Nastavení projektu a první pokusy 21. 8. 2009
- Django: Databázový model 28. 8. 2009
- Django: Databázový model podruhé 4. 9. 2009
- Django: Administrace 11. 9. 2009
- Django: Prezentace dat 18. 9. 2009
- Django: Prezentace dat podruhé 25. 9. 2009
- Django: Zpracovávání formulářů 2. 10. 2009
- Django: Autentizace a autorizace 9. 10. 2009
- Django: Nahrávání souborů 16. 10. 2009
- Django: Zabudované aplikace 23. 10. 2009
- Django: Rozšiřování možností Djanga 30. 10. 2009
- Django: Internacionalizace 6. 11. 2009
- Django: Nasazování projektu 13. 11. 2009
- Django: Kešování a škálování 20. 11. 2009
- Django: Závěr 27. 11. 2009
Nálepky:
Nastavení projektu
V adresáři projektu, který jsme si minule založili, se nalézá soubor settings.py
. Nejedná se o konfigurační soubor v klasickém slova smyslu, je to normální pythonový skript obsahující konstanty s nastavením. A na ty se teď podíváme. Stačí si soubor otevřít v libovolném textovém editoru.
.py
) napsat magický komentář # coding: utf-8
.Přehled všech možností konfigurace lze nalézt v oficiální dokumentaci. Teď si nastavíme pouze ty konstanty, které budou v tomto díle seriálu potřeba, u ostatních ponecháme výchozí nastavení. Konkrétně se jedná o umístění adresáře se statickými soubory a s šablonami. Ty si nejprve vytvoříme v adresáři projektu. Obvykle se adresář pro statické soubory jmenuje static
a ten pro šablony templates
. Jakmile je máme vytvořené, stačí přepsat řádky s příslušnými konstantami na nové hodnoty:
MEDIA_ROOT = '/home/dqd/hrajeme_si/static/'
MEDIA_URL = '/static/'
TEMPLATE_DIRS = (
'/home/dqd/hrajeme_si/templates/',
)
Konstantu MEDIA_ROOT
je potřeba nastavit na absolutní cestu k adresáři se statickými soubory. Související konstanta MEDIA_URL
odkazuje na webovou adresu toho stejného adresáře, která se bude používat v HTML kódu projektu. A poslední nastavení, TEMPLATE_DIRS
, obsahuje absolutní cesty k adresářům se šablonami. Těch může být víc, my se zatím spokojíme s jedním. Vzhledem k tomu, že zřejmě nemáte projekt ve stejném adresáři jako já, budete muset konstanty MEDIA_ROOT
a TEMPLATE_DIRS
nastavit trochu jinak.
'C:/Users/Uživatel/soubor.txt'
.Naše první aplikace
Minulý týden jsem sliboval, že si něco naprogramujeme. S programem vypisujícím aktuální čas sice díru do světa neuděláme, ale každý musí nějak začínat.
Založení aplikace
První krok spočívá v založení aplikace. Aplikace je součást projektu, která nám poskytuje nějakou funkcionalitu. Například tady na Zdrojáku by jedna aplikace mohla obsluhovat články a zprávičky, jiná aplikace by zajišťovala registraci, uživatelský profil a jeho správu. Jeden projekt obvykle obsahuje více aplikací. Stejně tak se jedna aplikace může vyskytovat ve více projektech.
Příkaz pro založení aplikace je python manage.py startapp <nazev_aplikace>
. Pokud tedy chceme založit například aplikaci s názvem pokus, napíšeme příkaz python manage.py startapp pokus
. Poté se vytvoří adresář stejného jména, obsahující několik souborů:
$ ls pokus/
__init__.py models.py tests.py views.py
Ahoj, světe!
Následující kód napíšeme do souboru views.py
, který je určen pro zpracovávání dat pomocí pohledů (views). Náš první pokus o vypsání aktuálního času by mohl vypadat nějak takhle:
from datetime import datetime from django.http import HttpResponse def current_time(request): return HttpResponse(datetime.now().strftime('%H:%M:%S'))
První dva řádky importují z modulu datetime
stejnojmennou třídu a z modulu django.http
třídu HttpResponse
, takže jsou připraveny k použití. Dále si definujeme funkci (tedy pohled) current_time
, která má jediný parametr, objekt request
. Všechny pohledy mají první parametr stejný a je konvence ho tak pojmenovávat. Objekt request
(instance třídy HttpRequest
) obsahuje užitečné informace týkající se HTTP dotazu, jako GET a POST parametry, proměnné serveru apod. Přehled všech možností tříd HttpRequest
a HttpResponse
lze nalézt v dokumentaci.
V posledním řádku kódu vrátíme HTTP odpověď. Zavoláním metody datetime.now()
získáme aktuální datum a čas a pomocí další metody strftime
jej zobrazíme ve tvaru hodiny:minuty:sekundy. To vytvoří řetězec s aktuálním časem.
Ale to není vše, potřebujeme ještě přiřadit našemu pohledu adresu. Konstanta ROOT_URLCONF
odkazuje na hlavní soubor s definicemi propojení URL s konkrétními pohledy. Ve výchozím nastavení se jedná o soubor urls.py
, který nalezneme v adresáři projektu. Vymažeme jeho obsah a vložíme tam následující kód:
from django.conf.urls.defaults import * urlpatterns = patterns('hrajeme_si', (r'^time/$', 'pokus.views.current_time'), )
Opět je zde import důležitých součástí, hlavně funkce patterns
. Tato funkce bere jako první parametr prefix, ze kterého se budou načítat pohledy (v našem případě projekt hrajeme_si) a další parametry jsou už jenom n-tice, obsahující regulární výraz s adresou a samotný pohled. Znak stříšky v regulárním výrazu označuje, že odkaz musí daným textem začínat, znak dolaru označuje, že tím musí končit. Počáteční lomítko se vynechává, protože všechny adresy začínají lomítkem. Tedy odkaz na index webu (/) by se zapsal regulárním výrazem r'^$'
.
Pohled se zadává ve formě podobné adresářové struktuře, jenom se místo lomítek odděluje tečkami a vynechávají se pythonové koncovky. Zápis 'hrajeme_si.pokus.views.current_time'
by tedy znamenal projekt hrajeme_si, aplikace pokus, soubor views.py a funkce current_time.
Když soubory uložíme a nastartujeme vývojový server (příkaz python manage.py runserver
), zobrazí se nám na adrese http://127.0.0.1 :8000/time/ aktuální čas.
Značkování podle šablony
Předchozí příklad vrací odpověď ve formě prostého textu. Samozřejmě bychom mohli začít vkládat HTML tagy přímo do pohledu, ale to odporuje principu oddělení dat od jejich prezentace. (Vzpomínáte si na zmínku o MTV architektuře v minulém dílu? Tohle je přesně ono.) Proto si raději založíme HTML šablonu, které přepošleme objekt s aktuálním časem a čas naformátujeme tam. Pojmenujeme ji třeba time.html
a uložíme do adresáře pro šablony (viz nastavování konstanty TEMPLATE_DIRS
):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Ahoj, světe!</title> </head> <body> <h1>Aktuální čas</h1> <p>{{ current_time|time:'H:i:s' }}</p> </body> </html>
Jak můžeme vidět, šablona se příliš neliší od obyčejné HTML stránky, jenom část {{ current_time|time:'H:i:s' }}
je poněkud nestandardní. Zápis {{ var }}
označuje místo, kde se má vypsat proměnná. Část za svislítkem je filtr time
, který naformátuje náš čas podle zadaných kritérií. (Všimněte si, že se použité formátovače liší od těch v metodě strftime
.)
Dále musíme upravit náš pohled tak, aby pracoval se šablonou:
from datetime import datetime from django.shortcuts import render_to_response def current_time(request): return render_to_response('time.html', {'current_time': datetime.now()})
Django obsahuje velké množství funkcí, které nám ulehčují život, a render_to_response
je jedna z nich. Místo toho, abychom museli načíst soubor se šablonou, zpracovat jej a vrátit odpověď, stačí nám pouze poskytnout název souboru s šablonou a proměnné, které do ní pošleme, víc nic. Ty se zadávají v pythonovém slovníku, kde klíče označují název proměnné. Pokud bychom jich chtěli zadat víc, stačí je v tom slovníku oddělit čárkou.
Zprovoznění statických souborů
Poslední věc, kterou si dnes ukážeme, je přístup ke statickým souborům. Bude se to hodit, až budeme chtít aplikace přizpůsobovat. Mezi statické soubory patří veškerý obsah, který chceme poslat klientovi bez předchozího zpracování na serverové straně — typicky obrázky, kaskádové styly a klientské skripty. Následující kód je potřeba vložit na úplný konec souboru urls.py
:
from django.conf import settings if settings.DEBUG: urlpatterns += patterns('', (r'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:], 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), )
Místo vysvětlování principu si pouze otestujeme funkčnost. Když do našeho adresáře se statickými soubory nahrajeme nějaký soubor, třeba PNG obrázek s názvem test.png
, měli bychom na adrese http://127.0.0.1 :8000/static/test.png tento obrázek vidět. Tento postup je určen pouze pro vývojové účely, z výkonnostních důvodů se při „ostrém“ provozu statické soubory většinou nechávají posílat přímo webserverem (např. z jiné domény).
Související odkazy
- Nastavení a tutoriál na Djangoproject.com
- Tutoriál na Djangoproject.cz
- Třetí kapitola v The Definitive Guide to Django
Příště se podíváme na databázový model a začneme stavět složitější aplikaci.
Neměl by být ten komentář vypadat takto?
# –– coding: utf-8 ––
Fórum asi filtruje hvězdičky, tak tedy znovu:
# -*- coding: utf-8 -*-
Ano, lze to zadávat i takto, jediný rozdíl je v tom, že tento zápis podporují některé editory (např. emacs) a nastaví podle toho kódování. Jinak je to úplně stejné. Více se dá dozvědět na odkazu z článku http://www.python.org/…ps/pep-0263/.
Ještě drobnost:
Django mi při použití kódu šablony z ukázky vyhodí parse error. Když se místo apostrofů ve filtru použijí uvozovky, funguje to v pořádku.
{{ current_time|time:"H:i:s" }}
Máte naprostou pravdu, ve starších verzích (minimálně v 1.0.2) Djanga zadávání argumentů filtrům pomocí jednoduchých uvozovek nefunguje. Aktuální verze 1.1 to zvládá bez problémů. Je zajímavé, že v dokumentaci o tom není žádná zmínka a ani v changelogu ne. Každopádně díky za ohlášení, pokusím se s tím něco udělat.
V souboru settings.py jsme nechali TIME_ZONE = ‚America/Chicago‘. Je třeba to opravit na naše:
TIME_ZONE = 'Europe/Prague'
Díky za upozornění, v původním textu jsem tu konstantu měl popsanou, pak jsme se to rozhodli celé přepsat a na tohle jsem úplně zapomněl.
Absolutní cesty nejsou zrovna dobrý nápad.
Nefunguje něco takového?
cp=os.getcwd()
MEDIA_ROOT = cp+‚/static/‘
funguje os.path.realpath(os.path.dirname(__file__))
více na http://zeroandone.posterous.com/top-10-tips-to-a-new-django-developer nebo http://morethanseven.net/2009/02/11/django-settings-tip-setting-relative-paths/
Jaká máte oblíbená vývojový prostředí?
Pracuje někdo stylem Test Driven Development? S čim?
Na Python používám Komodo Edit a
vim
. Techniku TDD nevyužívám, ale myslím si, že v některých projektech má své opodstatnění.Preklep vo vzorovom zapise premennych v subore „settings.py“ je zrejmy z kontextu a preto by nemal byt problem tento zapis vykonat korektne, ale pre istotu. ;)
MEDIA_ROOT = “
MEDIA_URL = “
STATIC_ROOT = ‚C:/Users/../hrajeme_si/static/‘
STATIC_URL = ‚/static/‘