Escolar Documentos
Profissional Documentos
Cultura Documentos
Poniewa Django powstawao w rodowisku dziennikarskim, gdzie szybko ma niebywae znaczenie, zostao tak zaprojektowane, by mc szybko i atwo wykonywa typowe zadania zwizane z tworzeniem stron internetowych. Oto krtki i nieformalny opis tego, jak napisa w Django aplikacj wykorzystujc baz danych do przechowywania informacji. Celem tego dokumentu jest przedstawienie wystarczajcego opisu technicznego, by zrozumie, jak dziaa Django, ale nie jest to wiczenie ani opis poszczeglnych funkcji. Zajrzyj do naszej szczegowej dokumentacji Django, jeli stwierdzisz, e chcesz zacz nowy projekt.
Instalacja modelu
Skorzystaj z narzdzia administracyjnego z wiersza polece, by automatycznie utworzy tabele bazy danych:
manage.py syncdb
Polecenie syncdb analizuje wszystkie dostpne modele i tworzy te tabele bazy danych, ktre jeszcze w niej nie istniej.
Za darmo otrzymujesz bogaty interfejs programistyczny w Pythonie zapewniajcy dostp do danych. API powstaje w locie, nie jest potrzebna adna generacja kodu:
>>> from mysite.models import Reporter, Article # W systemie nie ma jeszcze adnych reporterw. >>> Reporter.objects.all() [] # Utwrz nowego reportera (obiekt klasy Reporter). >>> r = Reporter(full_name='Jan Kowalski') # Zapisz obiekt w bazie danych. Musisz jawnie wywoa metod save(). >>> r.save() # Teraz obiekt ma nadany identyfikator. >>> r.id 1 # Reporter znajduje si w bazie danych. >>> Reporter.objects.all() [Jan Kowalski] # Pola bazy s atrybutami Pythonowego obiektu. >>> r.full_name 'Jan Kowalski' # Django udostpnia bogaty interfejs do wyszukiwania danych. >>> Reporter.objects.get(id=1) Jan Kowalski >>> Reporter.objects.get(full_name__startswith='Jan') Jan Kowalski >>> Reporter.objects.get(full_name__contains='walsk') Jan Kowalski >>> Reporter.objects.get(id=2) Traceback (most recent call last): ... DoesNotExist: Reporter does not exist for {'id__exact': 2} # Utwrz artyku. >>> from datetime import datetime >>> a = Article(pub_date=datetime.now(), headline='Django jest super', ... article='Racja.', reporter=r) >>> a.save() # Teraz artyku znajduje si w bazie danych. >>> Article.objects.all() [Django jest super] # Obiekt artykuu umoliwia atwy dostp do powizanego z nim obiektu reportera. >>> r = a.reporter >>> r.full_name 'Jan Kowalski' # I odwrotnie: # Obiekt reportera umoliwia atwy dostp do powizanych z nim artykuw. >>> r.article_set.all() [Django jest super] # Interfejs automatycznie wykorzystuje zwizki tak daleko, jak to bdzie
# potrzebne, stosujc zczenia bazodanowe (Django doda je automatycznie). # Przedstawiony przykad znajduje wszystkie artykuy reportera, ktrego imi # zaczyna si na "Jan". >>> Article.objects.filter(reporter__full_name__startswith="Jan") [Django jest super] # Zmie obiekt, modyfikujc jego atrybuty i wywoujc metod save(). >>> r.full_name = 'Piotr Nowak' >>> r.save() # Usu obiekt metod delete(). >>> r.delete()
Filozofia jest nastpujca Ty, Twj klient lub zesp redakcyjny edytujecie dane witryny. Nie chcesz wic powica czasu na tworzenie osobnych interfejsw administracyjnych tylko do zarzdzania zawartoci. W Django bardzo czsto zdarza si, e modele powstaj bardzo szybko wraz z wczonym systemem administracyjnym, by zesp redakcyjny (lub klienci) mogli zacz wypenia dane. Programici i projektanci mog si w tym czasie zaj utworzeniem publicznie dostpnej czci interfejsu.
from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^artykuly/(\d{4})/$', 'mysite.views.year_archive'), (r'^artykuly/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'), (r'^artykuly/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'), )
Odwzorowanie polega na znalezieniu pasujcego wyraenia regularnego, a nastpnie wywoanie odpowiadajcej mu funkcji widoku (ang. view). Wyraenia regularne stosuj nawiasy do wyapania wartoci z adresw URL. Gdy uytkownik wysya danie pobrania strony, Django przechodzi po kolei przez kady z wzorcw i zatrzymuje si na pierwszym, ktry odpowiada danemu adresowi URL. (Jeli dopasowania nie uda si znale, Django wywouje specjalny widok dla bdu 404). Rozwizanie to jest wyjtkowo szybkie, poniewa Django kompiluje wyraenia regularne w trakcie uruchamiania aplikacji serwerowej. Gdy Django znajdzie pasujce wyraenie regularne, importuje i wywouje wskazany widok, ktry jest zwyk Pythonow funkcj. Do kadego widoku trafia obiekt dania zawierajcy metadane dania oraz wartoci zebrane podczas analizy wyraenia regularnego. Jeli na przykad uytkownik zada adresu URL /artykuly/2005/05/39323/, Django wywoa funkcj mysite.views.article_detail(request, '2005', '05', '39323').
Napisz widoki
Kady widok odpowiada za wykonanie jednej z dwch rzeczy: zwrcenie obiektu HttpResponse zawierajcego zawarto danej strony lub zgoszenie wyjtku takiego jak Http404. To, co si bdzie dziao w jego wntrzu, zaley od Ciebie. Oglnie rzecz biorc widok pobiera dane zgodnie z przekazanymi parametrami, wczytuje szablon i renderuje go, wykorzystujc pobrane dane. Oto przykad widoku year_archive dla wczeniejszego przykadu z adresami URL:
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} )
Przykad wykorzystuje system szablonw Django, ktry ma kilka potnych funkcji, ale jednoczenie pozostaje na tyle prosty, by mg by wykorzystywany przez osoby niezaznajomione z programowaniem.
Zaprojektuj szablony
Przedstawiony powyej kod wczytuje szablon news/year_archive.html. Django wykorzystuje ciek wyszukiwania szablonw, ktra umoliwia minimalizacj redundancji midzy szablonami. W pliku ustawie okrela si list folderw, ktre naley
sprawdzi w poszukiwaniu szablonw. Jeli szablon nie istnieje w pierwszym folderze, sprawdza nastpny itd. Przypumy, e znaleziono szablon o nazwie news/article_detail.html. Oto jak mgby on wyglda:
{% extends "base.html" %} {% block title %}Artykuy z roku {{ year }}{% endblock %} {% block content %} <h1>Artykuy z roku {{ year }}</h1> {% for article in article_list %} <p>{{ article.headline }}</p> <p>Autor: {{ article.reporter.full_name }}</p> <p>Opublikowano dnia {{ article.pub_date|date:"Y-m-d" }}</p> {% endfor %} {% endblock %}
Zmienne otaczaj podwjne nawiasy klamrowe. Element {{ article.headline }} oznacza W tym miejscu wywietl zawarto atrybutu headline artykuu. Kropek nie uywa si tylko i wycznie pobierania atrybutw: mog rwnie suy do pobierania danych ze sownika, danych z indeksu lub wywoywania funkcji. Zauwa, e {{ article.pub_date|date:"Y-m-d" }} wykorzystuje Uniksowy znak potoku (znak |). To tak zwany filtr szablonu, ktry umoliwia konwersj wartoci zmiennej. W tym przypadku filtr daty formatuje dat zawart w obiekcie daty na wskazany tekst (format przypomina funkcj date z PHP; tak, to jedna z dobrych cech PHP). Moliwe jest tworzenie acucha filtrw. Moesz napisa wasne filtry. Moesz napisa wasne znaczniki szablonw, ktre wykonuj dowolny napisany przez Ciebie kod Pythona. Django stosuje pojcie dziedziczenia szablonw. To wanie tym zajmuje si fragment {% extends "base.html" %}. Oznacza on: Najpierw zaaduj szablon o nazwie base, ktry ma zdefiniowan okrelon liczb blokw, a nastpnie zastp oryginalne bloki poniszym kodem. W duym skrcie moemy powiedzie, e takie rozwizanie drastycznie zmniejsza powtarzanie kodu w szablonach: kady szablon definiuje tylko to, co jest w nim unikatowe. Oto przykadowy wygld szablonu base.html:
<html> <head> <title>{% block title %}{% endblock %}</title> </head> <body> <img src="sitelogo.gif" alt="Logo" /> {% block content %}{% endblock %} </body> </html>
Szablon definiuje oglny wygld witryny (razem z logo), a take wskazuje dziury do wypenienia przez szablony potomne. Takie rozwizanie znaczco upraszcza zmian wygldu witryny, bo wielu sytuacjach wystarczy zmieni tylko jeden plik szablon bazowy.
Umoliwia rwnie tworzenie wielu wersji danej witryny z rnymi szablonami bazowymi przy stosowaniu tych samych szablonw potomnych. Twrcy Django wykorzystali t technik do stworzenia cakowicie innej edycji witryny przystosowanej do telefonw komrkowych zrobili to, tworzc nowy szablon bazowy. Pamitaj, e nie musisz uywa systemu szablonw Django, jeli preferujesz inny. Cho system szablonw Django jest dobrze zintegrowany z warstw modelu Django, nic nie zmusza Ci do jego stosowania. Rwnie dobrze nikt nie zmusza Ci do stosowania systemu ORM wbudowanego w Django. Moesz wykorzysta inny mechanizm warstwy abstrakcji bazodanowej, czyta dane z plikw XML, czyta dane z plikw tekstowych lub robi cokolwiek innego. Kady element Django modele, widoki i szablony jest mocno odseparowany od pozostaych elementw.
To dopiero pocztek
Niniejszy tekst to bardzo skrtowy opis funkcjonalnoci dostpnej w Django. Oto niektre z innych uytecznych funkcji:
System cache integrujcy si z memcached i innymi mechanizmami (pliki, baza danych). System rozpowszechniania (en), ktry umoliwia tworzenie plikw dla czytnikw RSS i Atom poprzez pisanie niewielkich klas Pythonowych. Bardziej seksowne funkcje automatycznie generowanego panelu administracyjnego jest naprawd rozbudowany.
Nastpnym oczywistym krokiem jest pobranie Django, przerobienie tutoriala i doczenie do spoecznoci. Dzikujemy za zainteresowanie!
Instalacja Pythona
Jako pythonowy framework webowy Django wymaga Pythona. Django moe by uruchomiony na Pythonie 2.3 i nowszym. Moesz pobra Pythona ze strony http://www.python.org. Jeli uywasz Linuksa lub Mac OS X najprawdopodobniej masz ju go zainstalowanego.
Dla PostgreSQL potrzebujesz pakietu psycopg. Django wspiera zarwno wersj 1 jak i 2 (przy konfiguracji warstwy bazodanowej w Django, dla wersji 1 ustaw postgresql, a dla wersji 2 postgresql_psycopg2).
Jeli uywasz MySQL, bdziesz potrzebowa MySQLdb, w wersji 1.2.1p2 lub wyszej. Zapewne zainteresuj Ci te notki specyficzne dla tej bazy, zawarte na stronie MySQL backend. Jeli uywasz SQLite i Pythona w wersji 2.3 bd 2.4, bdziesz potrzebowa pysqlite. Uyj wersji 2.0.3 lub wyszej. Python 2.5 rozprowadzany jest z wrapperem sqlite w bibliotece standardowej, wic nie musisz w tym przypadku instalowa nic ponadto. Jeli uywasz Oracle, bdziesz potrzebowa cx_Oracle, w wersji 4.3.1 bd wyszej. Zapewne zainteresuj Ci te notki specyficzne dla tej bazy, zawarte na stronie Oracle backend.
Jeli planujesz uywa djangowego polecenia manage.py syncdb w celu zautomatyzowania procesu tworzenia tabel w bazie danych dla Twojego modelu, bdziesz musia mie pewno, e Django ma uprawnienia do tworzenia i modyfikowania tabel w uywanej przez ciebie bazie danych. Jeli planujesz tworzy tabele rcznie, moesz zwyczajnie nada Django uprawnienia SELECT, INSERT, UPDATE i DELETE. W przypadku niektrych baz danych Django bdzie potrzebowa uprawnie do ALTER TABLE w czasie wykonywania syncdb, lecz nie wpynie to na deklaracj ALTER TABLE tabeli ktra zostaa utworzona przez syncdb. Jeli uywasz frameworka testowego Django by zbada zapytania do bazy danych, bdziesz potrzebowa uprawnie do utworzenia testowej bazy danych.
(Zauwa, e powysza komenda powinna zosta wykonana w rodowisku powoki systemowej, nie w trybie interaktywnym Pythona)
Instrukcje instalacyjne mog si delikatnie rni, w zalenoci od tego czy instalujesz Django z paczek dla okrelonej dystrybucji, pobierasz ostatnie oficjalne wydanie czy moe ostatni wersj rozwojow. Bez wzgldu na to jak metod wybierzesz, instalacja Django jest naprawd prosta.
4. Nastpnie zadbaj o to by interpreter Pythona mg zaadowa kod Django. Jest wiele sposobw na wykonanie tej czynnoci. Jednym z najwygodniejszych na Linuksie, Mac OSX lub innym systemie uniksopodobnym jest uycie linka symbolicznego:
5. ln -s `pwd`/django-trunk/django SITE-PACKAGES-DIR/django
(W powyszej linii zmie SITE-PACKAGES-DIR tak by pasowa do lokalizacji katalogu site-packages w Twoim systemie, co zostao wytumaczone w sekcji powyej Gdzie si znajduje mj katalog site-packages?.) Alternatywnie, moesz zdefiniowa swoj zmienn systemow PYTHONPATH tak by zawieraa katalog django-trunk. Moe by to najwygodniejsze rozwizanie dla uytkownikw systemu Windows, ktry nie spiera linkw symbolicznych (zmienne rodowiskowe mog by definiowane w systemie Windows z Panelu Sterowania). 9
Co z Apache i mod_pythononem? Jeli wybrae rozwizanie z ustawieniem zmiennej PYTHONPATH, musisz pamita by zrobi to samo w konfiguracji Apache przy wdroeniu w rodowisku produkcyjnym. Ustaw PythonPath w pliku konfiguracyjnym Apache. Wicej informacji o wdraaniu jest dostpnych w naszej dokumentacji Jak uywa Django z mod_pythonem. 6. Na systemach uniksopodobnych utwrz link symboliczny do pliku djangotrunk/django/bin/django-admin.py w katalogu w twojej ciece systemowej, takim jak /usr/local/bin. Na przykad:
7. ln -s `pwd`/django-trunk/django/bin/django-admin.py /usr/local/bin
Zabieg ten pozwala wpisa django-admin.py z poziomu kadego katalogu zamiast wpisywania polecenia z pen ciek do pliku. Na systemie Windows mona osign ten sam rezultat kopiujc plik djangogdziekolwiek w swojej ciece systemowej,
Nie musisz uruchamia python setup.py install, poniewa dopiero co wykonae rwnowane dziaania w kokach 3 i 4. Jeli chcesz uaktualni swoj kopi kodu rdowego Django, po prostu wykonaj polecenie svn update z wntrza katalogu django-trunk. Subversion automatycznie pobierze wszelkie zmiany.
10
Publicznej - gdzie wywietlane s ankiety i mona na nie gosowa. Administracyjnej - ktra pozwala na dodawanie, edytowanie i usuwanie ankiet.
Zakadam, e posiadasz ju zainstalowane Django. Moesz to sprawdzi uruchamiajc interaktywny interpreter Pythona i wpisujc import django. Jeli to si powiedzie, bez adnych komunikatw bdw, oznacza to e posiadasz poprawnie zainstalowane Django. Gdzie szuka pomocy: Jeli masz problemy podczas przerabiania tego tutoriala, moesz napisa wiadomo na django-users lub doczy do kanau #django na serwerze irc.freenode.net gdzie sprbujemy Ci pomc.
Tworzenie projektu
Jeli to Twj pierwszy kontakt z Django, powi chwil na pocztkow konfiguracj. Oznacza to, e bdziesz musia wygenerowa kawaek kodu, ktry bdzie projektem Django zbiorem ustawie dla instancji Django, wczajc w to konfiguracj poczenia z baz danych, opcji specyficznych dla Django i Twojej aplikacji. W linii polece, wykonaj komend cd aby przej do katalogu gdzie chciaby trzyma swj kod, nastpnie wpisz django-admin.py startproject mysite. Stworzysz w ten sposb katalog mysite w biecym katalogu. Uprawnienia w Mac OS X Jeli uywasz Mac OS X, moesz zobaczy komunikat permission denied podczas prby wykonania django-admin.py startproject. Jest to spowodowane tym, e w systemach Uniksowych jak OS X, plik musi by oznaczony jako wykonywalny zanim moe zosta uruchomiony jako program. Aby to poprawi, otwrz Terminal.app, przejd (uywajc Komendy cd) do katalogu gdzie jest zainstalowany plik django-admin.py i wykonaj komend chmod +x django-admin.py. Note Powiniene unika nazywania projektw nazwami wbudowanych w Pythona lub nazwami komponentw Django. W szczeglnoci oznacza to unikanie nazw takich jak django (ktra bdzie kolidowa z samym Django) lub site (ktra spowoduje konflikt z wbudowanym w Pythona pakietem).
11
(Jeli instalowae Django poprzez python setup.py, django-admin.py powinno znajdowa si w twojej ciece systemowej. Jeli tak nie jest, powiniene j znale w sitepackages/django/bin, gdzie site-packages jest katalogiem z instalacj Pythona. Rozwa moliwo utworzenia dowizania symbolicznego do django-admin.py z jednego z folderw znajdujcych si w Twojej ciece systemowej, np. z /usr/local/bin.) Gdzie powinien znajdowa si kod Django? Jeli w przeszoci programowae w PHP, najprawdopodobniej przywyke do umieszczania swojego kodu w document root swojego serwera www (w miejscu takim jak /var/www). Z Django nie powiniene tego robi. Nie jest dobrym pomysem umiejscawianie jakiegokolwiek kodu Pythona wewntrz document root, poniewa stwarza to zagroenie moliwoci ogldania Twojego kodu przez odwiedzajcych. Nie jest do dobre ze wzgldw bezpieczestwa. Umie swj kod w ktrymkolwiek katalogu poza document root, w takim jak np.
/home/mycode.
Te pliki to:
__init__.py:
Pusty plik informujcy Pythona o tym, e katalog nadrzdny powinien by traktowany jako pakiet Pythona (zobacz wicej na temat pakietw). manage.py: Dziaajce z linii polece narzdzie, ktre pozwala na interakcj z projektem Django na rne sposoby. settings.py: Ustawienia/konfiguracja dla tego projektu Django. urls.py: Deklaracja adresw URL dla tego projektu Django; mapa serwisu Twojej strony zbudowanej w oparciu o Django.
Serwer deweloperski
Sprawdmy czy dziaa. Przejd do katalogu mysite, o ile jeszcze w nim nie jeste i uruchom polecenie python manage.py runserver. Powiniene zobaczy nastpujcy tekst na wyjciu linii polece:
Validating models... 0 errors found. Django version 1.0, using settings 'mysite.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
Wanie wystartowae serwer deweloperski Django, lekki serwer www napisany w caoci w Pythonie. Doczylimy go do Django by mg rozwija swj kod moliwie szybko, bez
12
potrzeby konfiguracji serwera produkcyjnego takiego jak Apache do momentu, a bdziesz gotowy do wdroenia produkcyjnego. Nadszed dobry moment by zauway: NIE UYWAJ tego serwera do niczego co choby przypomina rodowisko produkcyjne. Jest on przeznaczony jedynie do pomocy w procesie rozwijania wasnego kodu (nasz prac jest tworzenie frameworkw sieciowych a nie serwerw www). Teraz, kiedy serwer jest uruchomiony, odwied http://127.0.0.1:8000/ za pomoc swojej przegldarki internetowej. Powiniene zobaczy stron powitaln, w miych, jasnoniebieskich pastelowych kolorach. To dziaa! Zmiana portu Domylnie polecenie runserver uruchamia serwer deweloperski na porcie 8000. Jeli chcesz zmieni port serwera, przelij jego warto jako argument przy wywoaniu z linii polece. Dla przykadu - to polecenie uruchamia serwer na porcie 8080:
python manage.py runserver 8080
Pena dokumentacja dla serwera deweloperskiego znajduje si na stronie dokumentacji panelu admina.
Uwaga Jeli uywasz MySQL lub PostgreSQL, upewnij si e stworzye potrzebn baz danych. Moesz to wykona poleceniem CREATE DATABASE database_name; z wntrza powoki trybu aktywnego swojej bazy danych. Edytujc plik settings.py zwr uwag na ustawienia INSTALLED_APPS znajdujce si na samym dole. Ta zmienna przechowuje nazwy wszystkich aplikacji Django, ktre s aktywowane w biecej instancji Django. Aplikacje mog by uywane w wielu projektach -
13
moesz tworzy z nich pakiety i rozpowszechnia je aby inni mogli ich uywa w swoich projektach. Domylnie INSTALLED_APPS zawiera nastpujce aplikacje, wszystkie pochodzce od Django:
django.contrib.auth System uwierzytelniania. django.contrib.contenttypes Framework do trzymania typw modeli. django.contrib.sessions Framework sesji. django.contrib.sites Framework do zarzdzania wieloma stronami w jednej
instalacji Django. Te aplikacje s doczane domylnie w ramach wygody dla powszechnych przypadkw uycia. Kada z tych aplikacji uywa co najmniej jednej tabeli w bazie danych, ktre naley utworzy przed ich uyciem. By to zrobi, wywoaj nastpujce polecenie:
python manage.py syncdb
Komenda syncdb patrzy na ustawienia INSTALLED_APPS i tworzy wszystkie potrzebne tabele w bazie z uwzgldnieniem ustawie odnonie baz danych w Twoim pliku settings.py. Powiniene zobaczy informacj o kadej utworzonej przez niego tabeli i otrzyma zapytanie o utworzenie konta superuytkownika dla systemu uwierzytelniania. Moesz miao na to si zgodzi. Jeli jeste zainteresowany, uruchom klienta linii polece swojej bazy danych i wpisz \dt (PostgreSQL), SHOW TABLES; (MySQL) lub .schema (SQLite) celem wywietlenia tabel utworzonych przez Django. Dla minimalistw Jak wczeniej wspomnielimy, domylne aplikacje s doczone dla najpowszechniejszych zastosowa, ale nie kady ich potrzebuje. Jeli nie potrzebujesz ktrej lub wszystkich moesz zwyczajnie je za komentowa lub usun odpowiadajce jej/im linie z INSTALLED_APPS przed uruchomieniem syncdb. Komenda syncdb utworzy jedynie tabele dla aplikacji wymienionych w INSTALLED_APPS.
Tworzenie modeli
Teraz, kiedy twoje rodowisko jako projekt jest ustawione, jeste gotowy by zacz prac nad projektem. Kada aplikacja, ktr piszesz w Django, opiera si na pakietach Pythona, lecych gdzie w Twojej ciece dostpu Pythona, co wynika z pewnych konwencji. Na szczcie Django zapewnia zestaw narzdzi, ktre automatycznie generuj podstawow struktur aplikacji, wic moesz skupi si raczej na pisaniu kodu zamiast na tworzeniu katalogw. Projekty kontra aplikacje
14
Jaka jest rnica pomidzy projektem a aplikacj? Aplikacja co robi jest ni np. system blogowy, rejestr danych publicznych lub prosta ankieta. Projekt jest kolekcj konfiguracji i aplikacji dla okrelonej strony www. Projekt moe zawiera wiele aplikacji. Dana aplikacja moe by w wielu projektach. W tym tutorialu dla uatwienia utworzymy aplikacj ankiety w katalogu mysite. W konsekwencji aplikacja bdzie poczona z projektem to znaczy kod aplikacji ankiety bdzie odnosi si do aplikacji mysite.polls. Dalej w tym tutorialu omwimy jak uniezaleni Twoj aplikacj od dystrybucji. Aby utworzy aplikacj, upewnij si e jeste wewntrz katalogu mysite i wprowad nastpujce polecenie:
python manage.py startapp polls
Ta struktura katalogu bdzie przechowywa kod rdowy aplikacji ankiety. Pierwszym krokiem w pisaniu aplikacji www korzystajcej z bazy danych w Django jest zdefiniowanie modeli ukad w bazie danych z dodatkowymi metadanymi. Filozofia Model jest pojedynczym, definiujcym rdem na temat Twoich danych. Zawiera istotne pola i definiuje zachowania danych przez Ciebie przechowywanych. Django poda za Regu DRY. Celem jest zdefiniowanie Twojego modelu danych w jednym miejscu i automatyczne pobieranie z niego potrzebnych informacji. W naszej sondzie stworzymy dwa modele: sondy (Poll) i odpowiedzi (Choice). Sonda zawiera pytanie (question) i dat publikacji (pub_date), natomiast kada z odpowiedzi posiada pola: tre odpowiedzi (choice) i liczb oddanych gosw (votes). Kada odpowied jest powizana z konkretn sond. Te zaoenia s odwzorowane przez klasy napisane w Pythonie. Poddaj edycji plik aby wyglda tak jak poniej:
polls/models.py
from django.db import models class Poll(models.Model): question = models.CharField(max_length=200) pub_date = models.DateTimeField('data publikacji') class Choice(models.Model): poll = models.ForeignKey(Poll) choice = models.CharField(max_length=200) votes = models.IntegerField()
15
Bdy spowodowane max_length Jeli Django wyrzuca komunikaty bdw mwice e max_length nie jest poprawnym argumentem, najprawdopodobniej uywasz starej wersji Django (ta wersja tutoriala zostaa napisana dla najnowszej, rozwojowej wersji Django). Jeli korzystasz z rozwojowej wersji Django z Subversion (zobacz dokumentacj instalacyjn by uzyska wicej informacji), nie powiniene mie z tym adnych problemw. Jeli chcesz pozosta ze starsz wersj Django, bdziesz musia przej do tutoriala dla Django 0.96, poniewa ten tutorial omawia kilka waciwoci ktre istniej jedynie w wersji rozwojowej. Kod jest samo wyjaniajcy si. Kady model jest reprezentowany przez podklas, ktra dziedziczy z klasy django.core.meta.Model. Kady model posiada pewn liczb zmiennych, z ktrych kada reprezentuje pole w bazie danych. Kade pole jest reprezentowane jako instancja klasy meta.*Field np. models.CharField dla pl tekstowych i models.DateTimeField` dla obiektw datetime. Fakt ten pozwala Django stwierdzi, jakiego typu dane s przechowywane przez kade z pl. Nazwa kadej z instancji meta.*Field (np. question lub pub_date) jest nazw pola, tak jakiej oczekuje komputer. Bdziesz uywa tych nazw w swoim kodzie, a Twoja baza danych bdzie uywa ich jako nazwy kolumn. Moesz te uy opcjonalnego parametru dla pola aby przypisa mu dowoln, przyjazn czowiekowi nazw. Jest to uywane podczas introspekcji rnych czci Django, a take w dokumentacji. Jeeli tego pola nie ma, Django bdzie uywa nazwy zmiennej. W naszym przykadzie zdefiniowalimy tylko jedn przyjazn dla uytkownika nazw, dla pola Poll.pub_date. Dla wszystkich innych pl w tym modelu, nazwy zmiennych s wystarczajco czytelne dla czowieka. Niektre klasy Field wymagaj podania pewnych atrybutw. Klasa CharField na przykad oczekuje parametru max_length. Jest on uywany nie tylko przy tworzeniu struktury bazy danych, ale take podczas weryfikacji poprawnoci danych, o czym si niedugo sam przekonasz. Na koniec zauwa, e zostay zdefiniowane take relacje midzy klasami za pomoc models.ForeignKey. To mwi Django o powizaniach midzy kad z odpowiedzi a konkretn sond. Django obsuguje powizania: wiele-do-jednego (many-to-one), wiele-dowielu (many-to-many) i jeden-do-jednego (one-to-one).
Aktywacja modeli
Ta maa cz kodu modelu dostarcza Django mnstwa informacji. Z jego pomoc, Django moe:
Stworzy struktur bazy danych (wygenerowa kwerendy CREATE TABLE) dla tworzonej aplikacji. Stworzy API dostpu do bazy danych dla obiektw Poll i Choice.
16
Ale najpierw, musimy poinformowa nasz projekt e aplikacja polls (sonda) zostaa zainstalowana. Filozofia Aplikcje Django s wtyczkami (pluginami): moesz uywa ich w wielu projektach, a take rozpowszechnia, poniewa nie s one przypisane do konkretnej instalacji Django. Wyedytuj ponownie plik settings.py, i dopisz do INSTALLED_APPS mysite.polls. Teraz powinno to wyglda tak:
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'mysite.polls' )
Django wie teraz, e mysite zawiera aplikacj polls. Wykonaj teraz inn komend:
python manage.py sql polls
Treaz powiniene zobaczy nastpujcy cig polece CREATE TABLE dla Twojej ankiety:
BEGIN; CREATE TABLE "polls_poll" ( "id" serial NOT NULL PRIMARY KEY, "question" varchar(200) NOT NULL, "pub_date" timestamp with time zone NOT NULL ); CREATE TABLE "polls_choice" ( "id" serial NOT NULL PRIMARY KEY, "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"), "choice" varchar(200) NOT NULL, "votes" integer NOT NULL ); COMMIT;
Zauwa e:
Konkretna warto wyjciowa bdzie zalee od bazy danych jakiej uywasz. Nazwy tabel s generowane automatycznie poprzez kombinacj nazwy aplikacji (polls) i nazwy modelu zapisanej maymi literami poll i choice (moesz zmieni to domylne zachowanie). Klucze gwne (ID) s dodawane automatycznie (aczkolwiek moesz to zmieni). Django dodaje kocwk "_id" do zazw pl kluczy obcych (ForeignKey). Rwnie to zachowanie moesz jednak zmieni. Powizania z uyciem kluczy obcych s tworzone poprzez deklaracj REFERENCES. To jest cile powizane z baz danych ktrej uywasz, wic polecenia takie jak auto_increment (MySQL), serial (PostgreSQL) lub integer primary key (SQLite) specyficzne dla danego typu bazy s ustawiane automatycznie. To samo dotyczy si cytowania nazw p w zalenoci od bazy danych uywa si
17
pojedynczych bd podwjnych cudzysoww. Autor tego wprowadzenia uywa PostgreSQL, tak wic przykady s napisane dla tej bazy. Komenda sql nie wykonuje zapyta SQL na twoje bazie danych - jedynie drukuje je na ekranie by mg zobaczy jaki SQL Django uwaa na wymagany. Jeli chcesz, moesz skopiowa i wklei ten fragment kodu SQL na wejcie trybu interaktywnego swojej bazy danych. Jednake, jak wkrtce zobaczymy, Django zapewnia prost metod zatwierdzania tego SQL-a do Twojej bazy danych.
Sprawdza Twj model w poszukiwaniu jakichkolwiek bdw konstrukcyjnych. python manage.py sqlcustom polls Wypisuje wszelkie wasne zapytania SQL (takie jak modyfikacja tabeli lub ograniczenia (ang. constraints)) ktre s definiowane przez aplikacje. python manage.py sqlclear polls Wypisuje wymagane wyraenia DROP TABLE dla tej aplikacji, biorc pod uwag aktualnie istniejce tabele w Twojej bazie danych (jeli takowe istniej). python manage.py sqlindexes polls Wypisuje wyraenie CREATE INDEX dla tej aplikacji. python manage.py sqlall polls Kombinacja wszystkich wyjciowych wartoci wyrae SQL z polece sql, sqlcustom i sqlindexes.
python manage.py validate
Przejrzenie wynikw powyszych komend pomoe Ci zrozumie, co si dzieje pod podszewk Django. Wykonaj teraz syncdb ponownie by utworzy tabele tych modeli w Twojej bazie danych:
python manage.py syncdb
Komenda syncdb uruchamia polecenie SQL z sqlall na Twojej bazie danych dla wszystkich aplikacji z INSTALLED APPS ktre nie istniej aktualnie w Twojej bazie danych. Polecenie to tworzy wszystkie tabele, inicjalizuje dane i indeksuje dla kadej aplikacji ktr dodae do projektu od momentu ostatniego uruchomienia komendy syncdb. syncdb moe by wykonywane przez Ciebie tak czsto, jak Ci si to podoba tworzc tabele tylko wtedy, gdy nie istniej. Przeczytaj dokumentacj django-admin.py dowiedzie si o penych moliwociach manage.py.
Zabawy z API
Przejd teraz do interaktywnej powoki Pythona i powicz nieco wykorzystanie API dostarczone przez Django. By uruchomi powok Pythona uruchom komend:
python manage.py shell
Uywamy jej zamiast zwykego polecenia python, poniewa manage.py ustawia rodowisko projektu za nas. Ustawienie rodowiska polega na dwch rzeczach:
18
Dodaniu mysite do sys.path. Dla elastycznoci, kilka fragmentw Django odnosi si do projektw w Pythonie stosujc notacj z kropk (np. 'mysite.polls.models'). W zwizku z tym pakiet mysite musi znajdowa si w system.path. Niedawno widzielimy przykad takiego uycia: INSTALLED APPS przechowuje list pakietw we wspomnianej notacji z kropk.
Ustawieniu zmiennej DJANGO_SETTINGS_MODULE, ktra zapewnia Django ciek do Twojego pliku settings.py.
Praca bez wykorzystania manage.py Jeli nie chcesz uywa manage.py nie ma problemu. Po prostu upewnij si, e mysite na gwnym poziomie cieki dostpu Pythona (import mysite dziaa) i ustawia zmiennej rodowiskowej DJANGO_SETTINGS_MODULE warto mysite.settings. W celu uzyskania wikszej iloci informacji zobacz dokumentacj django-admin.py. Gdy ju bdziesz w shellu zbadaj API bazy danych:
# Zaimportuj modele klas ktre uprzednio napisalimy. >>> from mysite.polls.models import Poll, Choice # Na chwil obecn nie ma w systemie adnych ankiet. >>> Poll.objects.all() [] # Utwrz now ankiet Poll. >>> import datetime >>> p = Poll(question="Jak leci?", pub_date=datetime.datetime.now()) # Zapisz obiekt w bazie danych. Musisz wywoa metod save() jawnie. >>> p.save() # Teraz ma on swoje ID. Zauwa, e moe ono mie warto "1L" zamiast "1", # w zalenoci od tego jakiej bazy danych uywasz. To jednak drobnostka; # oznacza to jedynie tyle, e Twoja baza danych woli zwraca typ integer # jako obiekt long integer Pythona. >>> p.id 1 # Dostp do kolumn nastpuje przez atrybuty Pythona. >>> p.question "Jak leci?" >>> p.pub_date datetime.datetime(2007, 7, 15, 12, 00, 53) # Pozmieniaj wartoci zmieniajc atrybuty i wywoujc metod save(). >>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0) >>> p.save() # objects.all() wywietla wszystkie ankiety w bazie danych. >>> Poll.objects.all() [<Poll: Poll object>]
19
Chwila. <Poll: Poll object> jest wywietlany w formie mao pomocnej reprezentacji tego obiektu. Naprawmy to poprzez edycj modelu sondy (opisanego w pliku polls/models.py) i przecieniu metody __unicode__() w klasach Poll i Choice:
class Poll(models.Model): # ... def __unicode__(self): return self.question class Choice(models.Model): # ... def __unicode__(self): return self.choice
Gdy __unicode__() wydaje si nie dziaa Jeli dodae do swoich modeli metod __unicode__() i nie widzisz adnej zmiany w tym jak s reprezentowane, najprawdopodobniej uywasz starej wersji Django (ta wersja tutoriala zostaa napisana dla najnowszej, rozwojowej wersji Django). Jeli korzystasz z rozwojowej wersji Django z Subversion (zobacz dokumentacj instalacyjn by uzyska wicej informacji), nie powiniene mie z tym adnych problemw. Jeli chcesz pozosta ze starsz wersj Django, bdziesz musia przej do tutoriala dla Django 0.96, poniewa ten tutorial omawia kilka waciwoci ktre istniej jedynie w wersji rozwojowej. Przecianie metody __unicode__() w modelach jest wane nie tylko z powodu zwikszenia czytelnoci przy uywaniu powoki interaktywnej, ale take poniewa reprezentacje obiektw s uywane przez Django w automatycznie generowanym panelu administracyjnym. Dlaczego __unicode__() a nie __str__()? Jeli jeste obeznany z Pythonem, moesz mie nawyk dodawania do swoich klas metody __str__() a nie __unicode__(). Uywamy __unicode__() poniewa modele Django maj domylnie do czynienia z unikodem. Wszelkie dane trzymane w twojej bazie danych s konwertowane do unikodu zaraz po ich wycigniciu. Domylna metoda __str__() modeli Django wywouje __unicode__() i konwertuje rezultat na bytestringa UTF-8. Oznacza to, e unicode(p) zwraca cig znakw Unicode, za str(p) zwraca normalny cig znakw zakodowany jako UTF-8. Jeli wszystko co zostao wczeniej napisane nie ma dla Ciebie wikszego sensu, po prostu pamitaj doda do swoich modeli metod __unicode__(). Z odrobin szczcia wszystko powinno po prostu dziaa. Zwr uwag, e s to zwyke metody Pythona. Dla celw demonstracyjnych dodajmy wasn metod:
import datetime # ... class Poll(models.Model): # ...
20
Zauwa, e dodatkowa linia import datetime odnosi si do standardowego moduu Pythona datetime. Przejdmy z powrotem do interaktywnej powoki Pythona uruchamiajc ponownie python
manage.py shell: >>> from mysite.polls.models import Poll, Choice # Upewnij si e dodana przez nas metoda __unicode__() dziaa. >>> Poll.objects.all() [<Poll: Jak leci?>] # Django zapewnia bogate API bazy danych, ktre w caoci napdzane jest # nazywanymi argumentami >>> Poll.objects.filter(id=1) [<Poll: Jak leci?>] >>> Poll.objects.filter(question__startswith='Jak') [<Poll: Jak leci?>] # Pobierz ankiet, ktrej rok wynosi 2007. Oczywicie jeli wczeniej # w trakcie tego tutoriala wybrae inn dat, powiniene w tym momencie # wprowadzi odpowiedni warto. >>> Poll.objects.get(pub_date__year=2007) <Poll: Jak leci?> >>> Poll.objects.get(id=2) Traceback (most recent call last): ... DoesNotExist: Poll matching query does not exist. # Poszukiwanie obiektu na podstawie wartoci klucza gwnego jest # najczciej stosowanym przypadkiem, dlatego Django zapewnia odpowiedni # metod. # Ponisze jest identyczne z Poll.objects.get(id=1). >>> Poll.objects.get(pk=1) <Poll: Jak leci?> # Upewnij si e zdefiniowana przez Ciebie metoda dziaa. >>> p = Poll.objects.get(pk=1) >>> p.was_published_today() False # Docz do ankiety (Poll) kilka odpowiedzi (Choices). Wywoanie # konstruktora tworzy nowy obiekt odpowiedzi, wykonuje polecenie INSERT, # dodaje odpowied do listy dostpnych odpowiedzi i zwraca nowy obiekt # odpowiedzi (Choice). >>> p = Poll.objects.get(pk=1) >>> p.choice_set.create(choice='Specjalnie nic nowego', votes=0) <Choice: Specjalnie nic nowego> >>> p.choice_set.create(choice='Ciurkiem', votes=0) <Choice: Ciurkiem> >>> c = p.choice_set.create(choice='Znowu programuj', votes=0) # Obiekty wyboru (Choice) posiadaj API zapewniajce dostp do zwizanych # z nimi obiektami ankiety (Polls). >>> c.poll <Poll: Jak leci?>
21
# I odwrotnie: obiekty Poll posiadaj dostp do obiektw Choice. >>> p.choice_set.all() [<Choice: Specjalnie nic nowego>, <Choice: Ciurkiem>, <Choice: Znowu programuj>] >>> p.choice_set.count() 3 # Omawiane API automatycznie poda za relacjami tak daleko jak tego # potrzebujesz. Uyj podwjnego podkrelnika by oddzieli powizania. # Dziaa to dla tylu poziomw gbokoci dla ilu chcesz - nie ma limitu. # Znajd wszystkie Odpowiedzi (Choices) dla kadej ankiety opublikowanej # w roku 2007. >>> Choice.objects.filter(poll__pub_date__year=2007) [<Choice: Specjalnie nic nowego>, <Choice: Ciurkiem>, <Choice: Znowu programuj>] # Usu jedn z odpowiedzi. Uyj delete() aby tego dokona. >>> c = p.choice_set.filter(choice__startswith='Znowu program') >>> c.delete()
By uzyska wicej informacji na temat API do baz danych zobacz dokumentacj API do baz danych Gdy ju bdziesz czu si komfortowo uywajc wspomnianego wczeniej API, przeczytaj cz 2 tego tutoriala aby doda automatyczny panel admina.
Pytania/Wsparcie
Jeeli zauwaye bdy w tumaczeniu dokumentacji prosz zgo je nam.
22
Doda "django.contrib.admin" do ustawie INSTALLED_APPS. Wykona komend python manage.py syncdb. Jako, e dodae now aplikacj do INSTALLED_APPS, tabele w bazie danych musz zosta uaktualnione. Popraw swj plik mysite/urls.py oraz odkomentuj lini znajdujc si pod Uncomment this for admin:. Ten plik jest plikiem konfiguracyjnym dla URLi Twojej strony - bdziemy zgbia jego tajniki w nastpnej czci tutoriala. Na t chwil wystarczy Ci wiedzie, e rzutuje on adresy URL na Twoj aplikacj. Po dokonaniu wyej opisanych zmian powiniene plik urls.py ktry jest podobny do tego:
from django.conf.urls.defaults import * # Odkomentuj dwie linie pod spodem aby wczy aplikacje admina: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Przykad: # (r'^mysite/', include('mysite.foo.urls')),
23
# # # #
Odkomentuj linie admin/doc pod spodem oraz dodaj 'django.contrib.admindocs' do INSTALLED_APPS aby wczy dokumentacje admina: (r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Odkomentuj linie pod spodem aby wczy aplikacje admina: (r'^admin/(.*)', admin.site.root), )
(Wytuszczone linie, s liniami ktre powinny by odkomentowane aby wczy aplikacje admina)
Teraz otwrz przegldark internetow i przejd do /admin/ w swojej lokalnej domenie np. http://127.0.0.1:8000/admin/. Powiniene zobaczy ekran logowania do aplikacji administracyjnej.
Powiniene zobaczy rwnie kilka innych typw edytowalnych treci, w tym grupy, uytkownikw oraz strony. To jest podstawowa funkcjonalno, ktr Django dostarczana domylnie.
Teraz odwie stron panelu, by zobaczy zmiany. Zauwa, e nie musiae ponownie uruchomi serwera deweloperskiego serwer automatycznie przeaduje projekt, wic wszelkie zmiany bd od razu widoczne w Twojej przegldarce.
Kliknij Polls. Jeste teraz na wykazie wszystkich sond. Ta strona pokazuje wszystkie sondy znajdujce si w bazie danych i pozwala wybra jedn z nich do edycji. Teraz znajduje si tam tylko Jak leci? - czyli sonda ktr utworzylimy w pierwszej czci tutoriala:
Formularz zosta wygenerowany automatycznie na podstawie informacji z modelu sondy rnym rodzajom pl modelu (model.DateTimeField, model.CharField) odpowiadaj rne kontrolki HTML. Kady typ pola wie jak ma zosta wywietlony w panelu administracyjnym
25
do kadego pola DateTimeField dodawane s dodatkowe przyciski. Dla daty jest to Today (Dzisiaj) wraz z przyciskiem wywietlajcym okienko z mini kalendarzem, natomiast dla pola Time (Czas) s przypisane przyciski Now (Teraz) oraz drugi, sucy do pokazania okienka z list najczciej uywanych okrele czasu.
Save (Zapisz) zapisuje zmiany i wraca do listy obiektw danego rodzaju. Save and continue editing (Zapisz i kontynuuj edycj) zapisuje zmiany i przeadowuje stron dla tego obiektu Save and add another (Zapisz i dodaj nowe) zapisuje zmiany i przenosi do nowego, pustego formularza odpowiedniego dla danego rodzaju obiektu. Delete (Usu) wywietla ekran potwierdzajcy usunicie obiektu.
Zmie dat publikacji (Date published) sondy poprzez kliknicie skrtw Today (Dzisiaj) i Now (Teraz). Nastpnie kliknij Save and continue editing (Zapisz i kontynuuj edycj). Teraz wybierz History (Historia) w prawym grnym rogu strony. Zobaczysz list zmian dla tego obiektu dokonanych w panelu administracyjnym Django, wraz z dat i godzin zmiany oraz loginem osoby dokonujcej t zmian:
admin.site.register(Poll)
Powtrz ten wzorzec stwrz obiekt model admin, przeka go jako drugi argument do admin.site.register() za kadym razem gdy chcesz stworzy opcje admina dla obiektu. To spowodowao przesunicie pola Pub date na gr:
26
Nie ma to wikszego znaczenia przy tylko dwch polach, jednak dla formularzy z wiksz iloci pl ustawienie intuicyjnej kolejnoci jest wane ze wzgldw uywalnoci takiego formularza. A skoro ju mwimy o formularzach z wiksz iloci pl, moesz chcie je podzieli na zestawy:
class PollAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date']}), ] admin.site.register(Poll, PollAdmin)
Pierwszym elementem w kadej tupli (krotce) w atrybucie fieldsets jest nazwa zestawu. Teraz formularz wyglda tak:
Moesz przypisa do kadego zestawu konkretn klas jzyka HTML. Django posiada wbudowan obsug klasy "collapse" ktra wywietla wybrany zestaw pl jako pocztkowo
27
zwinite. Jest to uyteczne gdy mamy dugi formularz z kilkoma polami ktre s rzadziej uywane:
class PollAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ]
Teraz odpowiedzi do sondy s dostpne w panelu. Formularz dodawania odpowiedzi (Add choice) wyglda tak:
28
W powyszym formularzu pole Poll jest polem wyboru zawierajcym wszystkie sondy w bazie. Django wie, e pole ForeignKey powinno by reprezentowane w panelu administracyjnym jako pole <select>. W naszym przypadku tylko jedna sonda chwilowo zostaa zapisana. Zwr uwag na odnonik Add another (Dodaj inn) znajdujcy si obok pola Poll. Kady obiekt powizany kluczem obcym (ForeignKey) z innym obiektem dostaje taki link automatycznie. Jeli klikniesz Add another, zobaczysz okienko (popup) z formularzem do dodawania sond. Jeli dodasz now sond za pomoc tego okienka i klikniesz Save, Django zapisze now sond w bazie danych oraz uaktualni pole wyboru znajdujce si w formularzu odpowiedzi (Choice). Powyszy sposb nie jest najbardziej efektywn metod dodawania obiektw odpowiedzi do systemu. Byoby wygodniej, jeli mgby dodawa odpowiedzi do sondy bezporednio z formularza w ktrym tworzysz now sond. Skoro tak, to sprbujmy to wykona. Usu wywoanie register() dla modelu Choice. Nastpnie zmie rejestracje modelu Poll:
class ChoiceInline(admin.StackedInline): model = Choice extra = 3 class PollAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] admin.site.register(Poll, PollAdmin)
Powysza zmiana informuje Django: Obiekty odpowiedzi s edytowane z poziomu formularza sond. Domylnie dostarcz 3 zestawy pl odpowiedzi. Zaaduj stron Add poll ebymy mogli sprawdzi jak to wyglda:
29
Dziaa to w nastpujcy sposb: s tam 3 pola odpowiedzi jak zostao ustalone przez opcj ale za kadym razem gdy wrcisz do strony ju stworzonego obiektu, dostaniesz kolejne pole odpowiedzi (tzn. nie ma na sztywno ustawionego ograniczenia co do iloci powizanych obiektw ktre mona doda).
extra
Jest tylko jeden may problem: wywietlenie wszystkich powizanych wpisw zabiera mnstwo miejsca na ekranie. Z tego powodu, Django pozwala na inny sposb wywietlenia wewntrznie powizanych obiektw; musisz tylko zmieni deklaracje ChoiceInline:
class ChoiceInline(admin.TabularInline): #...
Z TabularInline (zamiast StackedInline), wtedy powizane obiekty bd wywietlane w bardziej skomasowany, tabelaryczny sposb:
30
Domylnie, Django pokazuje reprezentacj str() kadego obiektu. Oczywicie mona to troch dostosowa, tak, eby wywietla podane przez nas pola. Aby to zrobi, uyj opcji list_display, ktra jest krotk zawierajc nazwy pl do wywietlenia jako kolumny na stronie z list sond:
class PollAdmin(admin.ModelAdmin): # ... list_display = ('question', 'pub_date')
Dla sprawdzenia jak si sprawuje ta opcja, dodajmy tam nasz metod was_published_today z pierwszej czci tutoriala:
class PollAdmin(admin.ModelAdmin): # ... list_display = ('question', 'pub_date', 'was_published_today')
Moesz klikn na nagwku kadej z kolumn aby posortowa list sond po okrelonym parametrze nie dotyczy to kolumny was_published_today, poniewa sortowanie z uyciem wasnych metod nie jest obsugiwane przez Django. Zauwa te e nagwek kolumny dla pola was_published_today jest domylnie nazw danej metody (z podkrelnikami zamienionymi na spacje). Mona to te zmieni poprzez dodanie atrybutu short_description dla danej metody:
def was_published_today(self): return self.pub_date.date() == datetime.date.today() was_published_today.short_description = 'Published today?'
Teraz dodajmy kolejne usprawnienia do naszej listy: filtry (Filters). Dodaj nastpujc lini do PollAdmin:
list_filter = ['pub_date']
To spowodowao pojawienie si panelu bocznego Filter ktry pozwala na filtrowanie listy sond po polu pub_date:
31
Rodzaj wywietlanych filtrw zaley od rodzaju pola po ktrym chcemy filtrowa. Poniewa pub_date jest polem typu DateTimeField, Django wie e potrzebne bd opcje Any date (Kada data), Today (Dzisiaj), Past 7 days (Ostatnie 7 dni), This month (Ten miesic), This year (Ten rok). Zaczyna wyglda coraz lepiej. Dodajmy moliwo wyszukiwania:
search_fields = ['question']
Na grze strony pojawio si teraz pole wyszukiwarki. Gdy zostanie tam wpisana jaka fraza, Django przeszuka pola question. Moesz uy tylu pl ile potrzebujesz aczkolwiek pamitaj, e Django uywa tutaj kwerendy SQL LIKE, wic umieszczaj tu tylko te pola ktrych potrzebujesz. Na koniec, poniewa nasza sonda posiada daty, powinnimy pogrupowa nasze sondy po tym wanie polu. Dodaj ponisz linijk:
date_hierarchy = 'pub_date'
Teraz na grze strony pojawiy si pola uatwiajce nawigacj po dacie. Na samej grze pokazane s dostpne lata. Pniej miesice i dni. Pozostao mi jeszcze poinformowa Ciebie, e lista sond jest automatycznie dzielona na strony mieszczce domylnie do 50 obiektw. Stronicowanie listy sond, pole wyszukiwarki, filtry, grupowanie po datach i sortowanie po kolumnach wsppracuj ze sob tak jak tego oczekujesz.
Skopiuj teraz plik admin/base_site.html z domylnego katalogu szablonw Django (django/contrib/admin/templates) do podkatalogu admin w ktrymkolwiek z katalogw ktre ustawie w TEMPLATE_DIRS. Na przykad jeli umiecie w TEMPLATE_DIRS linijk
32
/home/my_username/mytemplates, jak powyej, to skopiuj django/contrib/admin/templates/admin/base_site.html do katalogu /home/my_username/mytemplates/admin/base_site.html. Nie zapomnij podkatalogu admin.
o tym
Teraz wystarczy zmieni skopiowany plik zastpujc domylne teksty Django swoimi. Zauwa, e kady domylny szablon Django moe zosta nadpisany. Aby to zrobi, zrb dokadnie to samo co zrobie przed chwil z base_site.html skopiuj go z domylnego katalogu do swojego, i wykonaj zmiany. Uwani czytelnicy mog zapyta: skoro TEMPLATE_DIRS by domylnie pusty, jak Django wyszukiwa domylne szablony do panelu administracyjnego ? Odpowied: domylnie, Django automatycznie szuka w podkatalogu templates/ kadej aplikacji. Zajrzyj do loader types documentation (en), eby dowiedzie si wicej.
Aby dowiedzie si wicej o dostosowywaniu wygldu panelu administracyjnego Django, zajrzyj na Django admin CSS guide (en). Kiedy ju poznasz panel administracyjny Django, przeczytaj trzeci cz tego tutoriala aby zacz tworzy publicznie widoczn stron aplikacji.
Pytania/Wsparcie
Jeeli zauwaye bdy w tumaczeniu dokumentacji prosz zgo je nam.
33
strona gwna - wywietla kilka ostatnich wpisw; strona z wpisem - strona zawierajca kompletny pojedynczy wpis; archiwum, strona roczna - zawiera list wszystkich miesicy z wpisami z danego roku; archiwum, strona miesiczna - j.w., ale z list dni; archiwum, strona jednodniowa - strona z list wpisw z danego dnia; dodawanie komentarza - pozwala na dodawanie komentarzy przez czytelnikw.
archiwum - zawiera kilka ostatnich sond; strona z sond - wywietla sam sond; wyniki - podgld wynikw danej sondy; gosowanie - pozwala odda gos w wybranej sondzie.
ROOT_URLCONF
Django porwnuje URL do ktrego uytkownik zada dostpu z list wyrae regularnych zaczynajc od pierwszego na licie, i koczc na pierwszym pasujcym. Kiedy znajdzie odpowiednie wyraenie regularne, wywouje pasujc funkcj Pythona z referencj do obiektu HTTPRequest jako pierwszym argumentem, wszystkie wychwycone z wyraenia regularnego wartoci jako argumenty kluczowe, i argumenty z opcjonalnego sownika (trzecia opcja w tupli).
34
Aby dowiedzie si wicej o HTTPRequest zajrzyj do dokumentacji da i odpowiedzi (en) Django. Wicej informacji na temat URFconfs zobacz dokumentacj URLconf (en). Kiedy wywoae django-admin.py startproject mysite na pocztku pierwszej czci tutoriala, stworzye domylne ustawienie URLconf w mysite/urls.py. Rwnoczenie ustawia zmienn ROOT_URLCONF aby wskazywaa na plik:
ROOT_URLCONF = 'mysite.urls'
Warto si temu przyjrze. Kiedy kto zada ktrej podstrony z Twojego serwisu - na przykad /polls/23/, Django zaaduje modu mysite.urls poniewa jest on wskazywany przez ustawienie ROOT_URLCONF. Tam wyszukuje zmienn urlpatterns i przeszukuje j w poszukiwaniu pasujcego wyraenia regularnego. Kiedy je znajdzie r'^polls/(?P<poll_id>\d+)/$' - aduje wskazany modu lub pakiet: mysite.polls.views.detail. To odpowiada funkcji detail() w mysite/polls/views.py. Na koniec wywoana zostaje znaleziona funkcja detail() w nastpujcy sposb:
detail(request=<HttpRequest object>, poll_id='23')
Paramter poll_id=23 pochodzi z (?P<poll_id>\d+). Uywajc nawiasw wok wzorca (?P<nazwa>wzorzec) Django wyapuje pasujcy tekst do wzorca i przekazuje do wywoania funkcji jako nazwany parametr. Dla przykadu ?P<poll_id> definiuje nazw, a \d+ jest wzorcem ktry wpasowuje si w cig cyfr (tworzy w tym przypadki liczb). Poniewa URL patterns s wyraeniami regularnymi, tak naprawd nie ma adnych ogranicze z tym co za ich pomoc mona uzyska. I nie ma potrzeby dodawania URL cruft jak na przykad .php - dopki nie chcesz si wykaza odrobin humoru, w przypadku ktrego moesz zrobi tak:
(r'^polls/latest\.php$', 'mysite.apps.polls.views.index'),
Ale nie rb tego. To nic nie daje. Zwr uwag, e te wyraenie regularne nie przeszukuj parametrw GET i POST. Nie przeszukuj rwnie nazwy domeny. Dla przykadu, w zapytaniu na adres http://www.example.com/myapp/, URLconf przeszukuje tylko /myapp/. W zapytaniu o adresie http://www.example.com/myapp/?page=3, przeszukiwanie bdzie rwnie tylko cig znakw /myapp/.
35
Jeli potrzebujesz pomocy w stosowaniu wyrae regularnych, zajrzyj na stron Wikipedii lub dokumentacji Pythona (en). Moesz take zainteresowa si fantastyczn ksik wydawnictwa OReilly Matsering Regular Expressions autorstwa Jefrreya Friedla. Na koniec krtko o wydajnoci: te wyraenia regularne s kompilowane podczas pierwszego zaadowania moduu URLconf, dziki czemu s bardzo szybkie.
Pierwszy widok
Mamy na razie stworzony poprawny URLconf, ale nie mamy jeszcze adnego widoku. Zanim zaczniemy, trzeba sprawdzi czy Django poprawnie interpretuje nasze ustawienia. Uruchom wbudowany w Django serwer WWW:
python manage.py runserver
Teraz id do adresu http://localhost:8000/polls/ w swojej przegldarce. Powiniene ujrze adnie sformatowan stron bdu z nastpujcym komunikatem:
ViewDoesNotExist at /polls/ Tried index in module mysite.polls.views. Error was: 'module' object has no attribute 'index'
Ten bd wystpi poniewa nie stworzye jeszcze funkcji index() w pliku mysite/polls/views.py. Sprbuj take wywoa /polls/23/, /polls/23/results/ i /polls/23/vote/. Wywietlany bd informuje Ci ktry widok Django prbowa dopasowa do danego wywoania (i oczywicie mu si nie udao, poniewa jeszcze nie napisalimy adnego widoku). Czas na napisanie pierwszego widoku. Otwrz plik mysite/polls/views.py i wpisz tam nastpujcy kod:
from django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the poll index.")
To jest najprostszy z moliwych widokw. Odwied teraz /polls/ w przegldarce powiniene zobaczy tam powyszy tekst. Teraz dodaj tam kolejny widok (funkcje widoku). Wyglda nieco inaczej, poniewa pobiera argument (pamitaj e argumenty s wyapywane za pomoc wyrae regularnych z URLconf):
def detail(request, poll_id): return HttpResponse("You're looking at poll %s." % poll_id)
Zajrzyj ponownie pod adres /polls/34/. Wywietli on jakiekolwiek wpisane przez Ciebie w adresie ID sondy.
36
Wystpuje tam jeden problem, mianowicie: wygld strony jest na sztywno zakodowany w funkcji widoku. Jeli chciaby teraz zmieni wygld strony, musisz podda edycji kod widoku. Lepiej jest jednak uy systemu szablonw (ang. templates) Django aby oddzieli logik aplikacji od jej wygldu:
from django.template import Context, loader from mysite.polls.models import Poll from django.http import HttpResponse def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] t = loader.get_template('polls/index.html') c = Context({ 'latest_poll_list': latest_poll_list, }) return HttpResponse(t.render(c))
Powyszy kod pobiera szablon polls/index.html i przypisuje mu wartoci. Jako wartoci podaje mu sownik mapujcy nazwy zmiennych z szablonu na obiekty Pythona. Odwie stron. Teraz powiniene ujrze bd:
TemplateDoesNotExist: Your TEMPLATE_DIRS settings is empty. Change it to point to at least one template directory.
No tak, przecie nie mamy jeszcze adnego szablonu. Najpierw musimy stworzy katalog, gdzie w systemie plikw, do ktrego zawartoci Django bdzie mia dostp (Django dziaa z
37
uprawnieniami uytkownika ktry go uruchomi). Nie umieszczaj tego katalogu jako publicznie dostpnego ze wzgldw bezpieczestwa. Zmie TEMPLATE_DIRS w Twoim pliku ustawie (settings.py) aby poinformowa Django gdzie ma szuka szablonw - tak samo jak w drugiej czci tutoriala w upikszanie panelu administracyjnego. Kiedy ju to zrobisz, za katalog polls w swoim katalogu z szablonami. Nastpnie stwrz tam plik index.html.Zauwa, e loader.get_template(``polls/index.html)`` odpowiada plikowi [katalog szablonw]/polls/index.html w systemie plikw. Wypenij szablon polls/index.html:
{% if latest_poll_list %} <ul> {% for poll in latest_poll_list %} <li>{{ poll.question }}</li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}
Odwie stron w przegldarce - powiniene zobaczy list zawierajc jedn pozycj: Whats up z czci pierwszej tutoriala.
Skrt: render_to_response()
Bardzo czst wykonywan czynnoci jest zaadowanie szablonu, wypenienie go treci i zwrcenie obiektu HttpResponse z wyrenderowanym szablonem. Django pozwala uproci t procedur. Poniej jest nowa wersje widoku index():
from django.shortcuts import render_to_response from mysite.polls.models import Poll def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] return render_to_response('polls/index.html', {'latest_poll_list': latest_poll_list})
Zwr uwag, e nie ma potrzeby adowania moduu loader, Context czy HttpResponse. Funkcja render_to_response() przyjmuje jako argumenty nazw szablonu (pierwszy z argumentw) oraz sownik jako drugi argument. Zwraca HttpResponse podanego szablonu z uzupenion treci.
Wyjtek 404
Zajmijmy si teraz stron na ktrej wywietlana jest sonda. Oto potrzebny widok:
from django.http import Http404 # ... def detail(request, poll_id):
38
try: p = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404 return render_to_response('polls/detail.html', {'poll': p})
Nowoci jest tutaj rzucenie wyjtku django.http.Http404 jeeli sondy o podanym ID nie ma w bazie danych.
Skrt: get_object_or_404()
Inn czsto wykonywan czynnoci jest prba pobrania obiektu przy uyciu get() i rzucenie wyjtku Http404 jeli dany obiekt nie istnieje. Django pozwala na skrcenie tej operacji. Oto wersja widoku detail() z uwzgldnieniem skrtu:
from django.shortcuts import render_to_response, get_object_or_404 # ... def detail(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) return render_to_response('polls/detail.html', {'poll': p})
Funkcja get_object_or_404() pobiera jako pierwszy argument model Django, a jako drugi - okrelon liczb argumentw kluczowych, ktre nastpnie s przekazywane do funkcji get(). Jeli szukany obiekt nie istnieje, rzuca wyjtek Http404. Zaoenia Dlaczego uywamy funkcji get_object_or_404() zamiast automatycznie przechwytywa wyjtki DoesNotExist na wyszym poziomie, lub te dlaczego nasze API automatycznie nie rzuca wyjtkiem Http404 zamiast DoesNotExist? Poniewa to mieszaoby warstw modelu z warstw widoku. Jednym z gwnych zaoe projektowych Django jest zachowanie lunych powiza pomidzy nalecymi do projektu elementami skadowymi. Istnieje take funkcja get_list_or_404() ktra dziaa podobnie jak get_object_or_404(), z tym wyjtkiem, e uywa filter() zamiast get(). Rzuca wyjtkiem Http404 jeli lista jest pusta.
39
Zwr uwag na ustawienie handler404 w biecym module. Jak widzisz w django/conf/urls/defaults.py, handler404 zawiera domylnie django.views.defaults.page_not_found. Trzy informacje dotyczce widoku 404:
jest adowany take wtedy, gdy Django nie udao si przypasowa do adnego wyraenia regularnego zawartego w URLconf; jeli nie zmienisz domylnego widoku dla wyjtku 404, co zalecamy, cay czas pozostaje Ci do stworzenia szablon dla tego widoku: utwrz plik szablonu o nazwie``404.html`` gwnym katalogu szablonw, ten szablon domylnie zostanie uyty do obsugi wszystkich bdw 404; jeeli masz w swoich ustawieniach DEBUG ustawione na True, wtedy widok 404 nigdy nie bdzie uywany, tylko zamiast niego zostanie wywietlony lad bdu.
Uywanie szablonw
Wrmy do widoku detail() w naszej aplikacji. Jeli przekaemy warto poll do kontekstu nasz szablon (ang. template) moe wyglda tak:
<h1>{{ poll.question }}</h1> <ul> {% for choice in poll.choice_set.all %} <li>{{ choice.choice }}</li> {% endfor %} </ul>
System szablonw uywa skadni kropkowej w stylu Pythona aby uzyska dostp do zmiennych. W przykadzie {{ poll.question }} Django przeszukuje sownik obiektu poll. Gdy to si nie powiedzie, wyszukuje atrybuty - co w tym przypadku zakoczy si powodzeniem. Jeli atrybut nie zostaby znaleziony, Django sprbowaby wywoa metod question() w tym obiekcie. Wywoywanie metod dziaa w ptli {% for %}: poll.choice_set.all jest interpretowane jako kod Pythona poll.choice_set.all(), ktry zwraca list obiektw Choice i jest odpowiednie dla iteracji w tagu {% for %}. Zajrzyj do przewodnika po szablonach (en) jeli chcesz uzyska wicej informacji o szablonach.
Upraszczanie URLconfa
40
Pobaw si przez jaki czas widokami wraz z systemem szablonw. Gdy edytujesz URLconf, moesz zauway e sporo czci si w nim powtarza:
urlpatterns = patterns('', (r'^polls/$', 'mysite.polls.views.index'), (r'^polls/(?P<poll_id>\d+)/$', 'mysite.polls.views.detail'), (r'^polls/(?P<poll_id>\d+)/results/$', 'mysite.polls.views.results'), (r'^polls/(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'), )
Na przykad cz mysite.polls.views jest w kadym odwoaniu. Poniewa jest to do czsty przypadek, szkielet URLconf dostarcza sposobu na skrcenie przedrostkw. Moesz usun wszystkie przedrostki i wstawi je jako pierwszy argument do patterns():
urlpatterns = patterns('mysite.polls.views', (r'^polls/$', 'index'), (r'^polls/(?P<poll_id>\d+)/$', 'detail'), (r'^polls/(?P<poll_id>\d+)/results/$', 'results'), (r'^polls/(?P<poll_id>\d+)/vote/$', 'vote'), )
Powyszy zapis funkcjonalnie jest identyczny z poprzednim, ale jest znacznie krtszy i czytelniejszy.
Dzielenie URLconfs
Skoro ju przy tym jestemy, powinnimy teraz rozdzieli adresy naszej sondy od konfiguracji caego projektu. Aplikacje Django powinny by rozdzielne - powinna by moliwo przeniesienia kadej z nich do innej instalacji Django przy minimalnym nakadzie si. Nasza sonda jest jak na razie adnie oddzielona od samego projektu dziki cisej strukturze katalogw ktra zostaa utworzona przez python manage.py startapp, ale jedna jej cz jest ustawiana razem z innymi ustawieniami Django: URLconf. Konfigurowalimy ustawienia adresw w mysite/urls.py, ale adresy przygotowane dla aplikacji s specyficzne dla tej wanie aplikacji, a nie dla caego projektu - dlatego przeniemy je do katalogu aplikacji. Skopiuj plik mysite/urls.py do mysite/polls/urls.py`. Teraz z ``mysite/urls.py usu wszystkie adresy specyficzne dla sondy i wstaw tam wywoanie include():
(r'^polls/', include('mysite.polls.urls')),
Funkcja include() zwraca zawarto innego URLconfa. Zauwa e wyraenia regularne nie posiadaj koczcego $ (znak koca linii) ale posiada koczcy ukonik. Kiedy Django napotyka wywoanie include(), usuwa pasujc cz adresu i przekazuje pozosta cz do doczanego instrukcj include() URLconfa. Oto co si dzieje gdy uytkownik wywoa adres /polls/34/: 41
Django znajdzie pasujce '^polls/' usunie z wywoania pasujcy tekst przekae pozostay tekst (34/) do URLconfa mysite.polls.urls w celu dalszego przetworzenia.
Teraz, kiedy ju mamy to rozczone, musimy uproci URLconf mysite.polls.urls poprzez usunicie pocztkowego polls/ z kadej linii:
urlpatterns = patterns('mysite.polls.views', (r'^$', 'index'), (r'^(?P<poll_id>\d+)/$', 'detail'), (r'^(?P<poll_id>\d+)/results/$', 'results'), (r'^(?P<poll_id>\d+)/vote/$', 'vote'), )
Ide stojc za stworzeniem funkcji include() oraz rozbiciem URLconfa byo uatwienie czenia rnych aplikacji w cao. Teraz, kiedy sonda ma swojego wasnego URLconfa, moemy j atwo umieci w katalogu /polls/, lub /polls_fun/, /content/polls/, lub jakikolwiek innym, a nasza aplikacja cigle bdzie dziaa. Wszystkie aplikacje musz si zajmowa swoimi relatywnymi URLami, nie absolutnymi. Kiedy ju bdziesz dobrze orientowa si w temacie tworzenia widokw, przeczytaj czwart cz tutoriala aby nauczy si tworzenia prostych formularzy oraz oglnych widokw (generic view).
Pytania/Wsparcie
Jeeli zauwaye bdy w tumaczeniu dokumentacji prosz zgo je nam.
42
Szybkie wyjanienie:
Powyszy szablon wywietla przycisk typu "radio" dla kadego wyboru ankiety. Pole value dla kadego przycisku opcji jest skojarzone z ID obiektu choice. Atrybut name kadego przycisku opcji jest dostpny w "choice". To oznacza, e jeli kto wybiera jeden z przyciskw i wysya formularz form, to przegldarka otrzyma metod POST dane o zawartoci choice=3. Ustawilimy atrybut formularza action na /polls/{{ poll.id }}/vote/ oraz method na "post". Uywanie method="post" (zamiast method="get") jest bardzo wane, poniewa wysyanie formularza zmieni dane po stronie serwera. Jeeli kiedykolwiek tworzysz formularz, ktry zmienia dane po stronie serwera, uywaj method="post". Ta wskazwka nie ma nic wsplnego z Django, jest to dobra praktyka tworzenia aplikacji internetowych. forloop.counter oznacza ile razy znacznik for wykona kod wewntrz ptli. Wicej informacji znajdziesz w dokumentacji dla znacznika for.
Teraz utwrzmy widok Django, ktry obsuguje wysane dane oraz co z nimi robi. Pamitaj, e w tutorialu nr 3, utworzylimy URLconf dla aplikacji pools, zawierajcy linie:
(r'^(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'),
43
from django.shortcuts import get_object_or_404, render_to_response from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from mysite.polls.models import Choice, Poll # ... def vote(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) try: selected_choice = p.choice_set.get(pk=request.POST['choice']) except (KeyError, Choice.DoesNotExist): # Pokaz ponownie formularz do glosowania. return render_to_response('polls/detail.html', { 'poll': p, 'error_message': "Nie wybrales zadnej opcji", }) else: selected_choice.votes += 1 selected_choice.save() # Zawsze zwr HttpResponseRedirect po udanym obsueniu danych z POST. # To zapewnia, e dane nie zostan wysane dwa razy, jeeli uytkownik # kliknie w przegldarce przycisk Wstecz . return HttpResponseRedirect(reverse('mysite.polls.views.results', args=(p.id,)))
Ten kod zawiera kilka rzeczy, o ktrych jeszcze nie mwilimy w tym tutorialu:
jest obiektem przypominajcym sownik, ktry pozwala na dostp do otrzymanych danych po nazwie klucza. W tym przypadku request.POST['choice'] zwraca (jako tekst) ID wybranej opcji ankiety. Wartoci z request.POST s zawsze tekstem (obiektami string).
request.POST
Django dostarcza rwnie request.GET do pobierania w ten sam sposb danych z metody GET. W naszym kodzie uywamy jednak request.POST, aby upewni si, e dane bd zmieniane tylko przez wywoanie POST.
request.POST['choice'] zgosi wyjtek KeyError, jeeli choice nie by dostarczony w danych metody POST. Powyszy kod oczekuje wyjtku KeyError oraz wywietla ponownie formularz ankiety z informacj o bdzie, jeeli choice nie by podany. Po zwikszeniu liczby gosw (selected_choice.votes += 1), kod zwraca HttpResponseRedirect zamiast zwykego HttpResponse. HttpResponseRedirect przyjmuje pojedynczy argument: adres URL, do ktrego uytkownik zostanie przekierowany (zobacz kolejny punkt, jak tworzymy w tym przypadku adres URL). Zgodnie z komentarzem w kodzie, po udanym obsueniu danych z POST powiniene zawsze zwraca obiekt HttpResponseRedirect. To nie jest specyficzne dla Django; to po prostu dobra praktyka przy tworzeniu aplikacji internetowych. Uywamy funkcji reverse() w przekierowaniu HttpResponseRedirect. Ta funkcja pomaga unikn sztywnego wpisywania adresu URL w funkcji widoku. Jako parametr przekazujemy nazw widoku, ktry obsuy zapytanie oraz zmienne, ktre s uyte w tym adresie URL i wskazuj na ten widok. W tym przypadku, uywajc URLConf, ktry ustawilimy w tutorialu 3, wywoanie reverse() zwrci tekst podobny do tego: '/polls/3/results/'
44
gdzie 3 jest wartoci p.id. Ten przekierowany URL wtedy wywoa widok 'results', ktry wywietli kocow stron. Zwr uwag, e musisz tutaj uy penej nazwy widoku (cznie z prefiksem). Wicej informacji o reverse() moesz znale w dokumentacji URL dispatchera. Jak wspomniano w tutorialu 3, request jest obiektem HTTPRequest. Wicej o obiektach HTTPRequest znajdziesz w dokumentacji request and response. Po tym, jak kto zagosuje w ankiecie, widok vote() przekierowuje do strony z wynikami ankiety. Napiszmy widok:
def results(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) return render_to_response('polls/results.html', {'poll': p})
To prawie to samo co widok detail() z tutoriala nr 3. Jedyn rnic jest nazwa szablonu. Poprawimy ten zbyteczny kod pniej. Utwrzmy szablon results.html:
<h1>{{ poll.question }}</h1> <ul> {% for choice in poll.choice_set.all %} <li> {{ choice.choice }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }} </li> {% endfor %} </ul>
Teraz otwrz /polls/1/ w przegldarce i zagosuj w ankiecie. Powiniene zobaczy stron z wynikami, ktra jest uaktualniana za kadym razem, jak gosujesz. Jeeli wysyasz formularz bez wyboru na co gosujesz, powiniene zobaczy informacje o bdzie.
45
Przerbmy teraz nasz aplikacj ankiet, aby uywaa systemu widokw generycznych. Moemy wic skasowa troch kodu, ktry napisalimy wczeniej. Musimy tylko wykona kilka krokw, aby dokona tej konwersji. Dlaczego zmieniamy kod w ten sposb? Oglnie, gdy piszesz aplikacje w Django, musisz oceni czy widoki generyczne s dobrym rozwizaniem Twojego problemu. Jeeli tak, to bdziesz ich uywa od samego pocztku zamiast zmienia kod na kocu pisania aplikacji. Jednak w tym tutorialu celowo skupiamy si na pisaniu widokw od podstaw, aby pokaza podstawow koncepcje. Powiniene zna podstawy matematyki, aby mc korzysta z kalkulatora. Otwrz plik ustawie adresw URL polls/urls.py. Wyglda mniej wicej tak, zgodnie z tym, co napisalimy do tej pory:
from django.conf.urls.defaults import * urlpatterns = patterns('mysite.polls.views', (r'^$', 'index'), (r'^(?P<poll_id>\d+)/$', 'detail'), (r'^(?P<poll_id>\d+)/results/$', 'results'), (r'^(?P<poll_id>\d+)/vote/$', 'vote'), )
Uywamy tutaj dwch widokw generycznych: object_list oraz object_detail. Te dwa widoki s abstrakcj koncepcji wywietl list obiektw oraz wywietl stron ze szczegami dla konkretnego typu obiektu.
Kady widok generyczny musi wiedzie na jakich danych bdzie dziaa. Te dane podaje si w sowniku. Klucz queryset w tym sowniku wskazuje na list obiektw, ktre bd obsugiwane przez generyczny widok.
46
Widok generyczny object_detail oczekuje wartoci ID przekazanej z adresu URL, ktra nazywa si "object_id", wiec zmienilimy poll_id na object_id dla widokw generycznych. Dodalimy nazw poll_results do widoku wynikw, aby mie moliwo odwoania si do jego adresu URLa w pniejszym czasie (zobacz dokumentacj na temat konfigurowania wzorcw adresw URL, aby uzyska wicej informacji).
Uywamy tutaj take funkcji url() z pakietu django.conf.urls.defaults. Jest to dobry zwyczaj, aby uywa url() kiedy podaje si wzorzec taki, jak tutaj. Domylnie, widok generyczny object_detail uywa szablonu nazywajcego si <nazwa aplikacji>/<nazwa modelu>_detail.html. W naszym przypadku, uywa szablonu "polls/poll_detail.html". Zmie nazw szablonu polls/detail.html na polls/poll_detail.html oraz zmie wiersz render_to_response() w vote(). Podobnie, widok generyczny object_list uywa szablonu nazwywajcego si <nazwa aplikacji>/<nazwa modelu>_list.html. Zmie wic polls/index.html na polls/poll_list.html. Poniewa mamy wicej ni jeden wpis w URLconf, ktry uywa object_detail dla aplikacji polls, okrelamy rcznie nazw szablonu dla widoku wynikw: template_name='polls/results.html'. W przeciwnym razie obydwa widoki uywayby tego samego szablonu. Zauwa, e uywamy dict(), aby zwrci w tym miejscu zmieniony sownik. Note
all()
jest leniwe
To moe wyglda troch przeraajco: wywoanie Poll.objects.all() w widoku szczegu, ktry tylko potrzebuje jednego obiektu Poll, ale nie martw si; Poll.objects.all() jest waciwie specjalnym obiektem nazywanym QuerySet, ktry jest leniwy i nie wyciga nic z bazy danych, dopki nie musi. W czasie, gdy wystpi zapytanie do bazy, widok generyczny object_detail bdzie mia swj zasig zmniejszony do pojedynczego obiektu, wic ewentualne zapytanie wybierze z bazy danych tylko jeden wiersz. Jeeli chciaby si dowiedzie, jak to dziaa, zajrzyj do dokumentacji Django na temat API bazy danych, ktra wyjania leniw natur obiektw QuerySet. W poprzednich czciach tego tutoriala, szablony miay podany kontekst, ktry zawiera zmienne poll oraz latest_poll_list. Jednak widoki generyczne dostarczaj zmienne object oraz object_list jako kontekst. Dlatego musisz zmieni szablony, aby zawieray nowe zmienne kontekstu. Przejrzyj szablony i zmodyfikuj kade odniesienie do latest_poll_list na object_list. Zmie te kade wystpienie poll na object. Moesz teraz usun widoki index(), detail() oraz results() z polls/views.py. Ju ich nie potrzebujemy zostay zastpione przez widoki generyczne.
47
Widok vote() jest jednak cigle potrzebny. Musi by jednak zmodyfikowany, aby odpowiada nowemu kontekstowi zmiennych. W wywoaniu render_to_response(), zmie nazw zmiennej poll na object. Ostania rzecz do zrobienia to naprawa obsugi adresw URL z uwzgldnieniem uycia widokw generycznych. W widoku vote powyej uylimy funkcji reverse(), aby unikn sztywnego wpisywania adresw URL w widokach. Teraz przeczylimy si na widok generyczny, wic musimy zmieni wywoanie reverse(), aby wskazywao z powrotem do naszego widoku generycznego. Nie moemy ju po prostu uy funkcji widoku widoki generyczne mog (i s) uywane wielokrotnie ale moemy uy nazwy, ktrej uylimy:
return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
Uruchom teraz serwer i uyj nowej aplikacji ankiet opartej o widoki generyczne. Aby dowiedzie si wicej o widokach generycznych, zobacz dokumentacj widokw generycznych.
Ju wkrtce
Ten tutorial koczy si w tym momencie. Ale signij te po inne informacje:
Zaawansowane przetwarzanie formularzy Uywanie frameworka RSS Uywanie frameworka cacheowania Uywanie frameworka komentarzy Zaawansowane funkcje admina: uprawnienia Zaawansowane funkcje admina: Wasny JavaScript
W midzyczasie moesz przeczyta reszt dokumentacji Django i zacz pisa wasne aplikacje.
Pytania/Wsparcie
Jeeli zauwaye bdy w tumaczeniu dokumentacji prosz zgo je nam.
48
Django FAQ
Pytania oglne
Dlaczego ten projekt istnieje?
Django powstao w odpowedzi na konkretny problem: World Online, dzia WWW gazety w Lawrence, jest odpowiedzialny za intensywne tworzenie aplikacji internetowych z dziennikarskimi terminami. W szybko zmieniajcym sie rodowisku prasowym, World Online ma niekiedy tylko kilka godzin na wykonanie skomplikowanej aplikacji internetowej, liczc od koncepcji do publicznego uruchomienia. Jednoczenie deweloperzy World Online zawsze byli perfekcjonistami, jeeli chodzi o najlepsze praktyki tworzenia aplikacji internetowych. Pod koniec 2003 roku deweloperzy World Online (Adrian Holovaty i Simon Willison) zerwali z PHP i zaczli uywa Pythona do rozwijania serwisw internetowych. Podczas intensywnego tworzenia bogatych, interaktywnych serwisw, takich jak Lawrence.com, zaczli wydobywa wsplne elementy tworzenia serwisw internetowych, ktre pozwoliy im coraz szybciej budowa aplikacje. Stale ulepszali ten framework, dodajc coraz to nowe funkcje. Latem 2005 roku firma World Online zdecydowaa si na publiczne udostpnienie powstaego oprogramowania jako Django. Poniewa stworzenie Django nie byoby moliwe bez caej masy projektw wolnego oprogramowania Apache, Python, PostgreSQL oraz jeszcze kilku innych byli zachwyceni, e mog odwdziczy sie tym spoecznoci wolnego oprogramowania.
49
Tak. W porwnaniu do cakowitego kosztu budowy aplikacji internetowej, sprzt jest do tani. Dlatego te Django jest tak zaprojektowane, aby maksymalnie wykorzysta rodowisko sprztowe w ktrym bdzie pracowa. Django wykorzystuje architektur shared-nothing, co oznacza moliwo dodawania sprztu na dowolnym poziomie serwery baz danych, serwery cache oraz serwery WWW. Framework czysto rozdziela takie komponenty jak warstwa bazy danych i warstwa aplikacji. Dostarcza rwnie prosty (lecz o ogromnych moliwociach) framework cache.
50
Wilson Miner Projektowe sztuczki Wilcona sprawiaj, e czujemy si wszyscy jak gwiazdy rocka. Za dnia jest interaktywnym projektantem Apple. Nie pytaj go nad czym pracuje, bo bdzie musia Ci zabi. Mieszka w San Francisco. Na IRCu, Wilson jest znany jako wilsonian.
Django wydaje si by frameworkiem o wzorcu MCV, ale nazywacie kontroler widokiem, widok szablonem. Dlaczego nie uywacie standardowych nazw?
Podejcie do nazw standardowych jest dyskusyjne. W naszej interpretacji wzorca MVC, widok opisuje dane, ktre s prezentowane uytkownikowi. To niekoniecznie jak dane wygldaj, ale ktre dane s prezentowane. Widok opisuje, ktre dane widzisz, a nie jak je widzisz. To subtelna rnica. W naszym przypadku widok jest wywoaniem funkcji Pythona przez konkretny URL, dlatego e wywoanie funkcji opisuje, ktre dane s prezentowane. Ponadto, uwaamy za rozsdne oddziela zawarto od prezentacji w tym miejscu dochodzimy do szablonw. W Django widok opisuje, ktre dane s prezentowane, ale widok jest przekierowywany do szablonu, ktry opisuj jak dane s prezentowane. Gdzie w takim razie jest kontroler? W przypadku Django jest to prawdopodobnie sam framework: mechanizm, ktry wysya danie do odpowiedniego widoku zgodnie z konfiguracj URLi Django. Jeeli mielibimy stosowa skrty, moglibymy powiedzie, e Django jest frameworkiem MTV czyli model, szablon, widok. Mamy prac do zrobienia i ostatecznie liczy si efekt nie wane jak rzeczy si nazywaj. Django wg nas pozwala, wykona t prac w najbardziej logiczny sposb.
51
52
stronie Django oferuje wicej informacji ni wersja dostarczana ze stabilnym pakietem Django.
Pytania instalacyjne
Jak zacz?
1. 2. 3. 4. Pobierz rda. Zainstaluj Django (przeczytaj poradnik instalacyjny). Wykonaj tutorial. Przeczytaj dokumentacj i zadawaj pytania jeli tylko nie bdziesz umia sobie z czym poradzi.
Czy co trac uywajc Pythona 2.3 zamiast najnowszego, takiego jak Python 2.5?
Nie. Django samo w sobie gwarantuje e bdzie dziaa z kad wersj Pythona od 2.3 i wyszych. Oczywicie jeeli bdziesz uywa nowszej wersji Pythona ni 2.3, bdziesz w stanie skorzysta z nowych moliwoci jzyka jakie oferuje nowsza wersja Pythona razem ze zwikszeniem wydajnoci i pozostaymi optymalizacjami jakie zostay wykonane w samym jzyku Python. Mimo wszystko framework Django powinien dziaa tak samo dobrze z Pythonem 2.3 jak i 2.4 czy 2.5.
53
Dla Pythona 2.4, pobierz build win32 dla mod_pytona dla Pythona 2.4 (en). Dla Pythona 2.4, sprawd ten poradnik Django na Windows (en). Dla Pythona 2.3, pobierz mod_pythona z http://www.modpython.org/ i przeczytaj Uruchamianie mod_pythona na Apache na Windows2000 (en). Zobacz take to (nie zwizane z Windowsem) Poradnik jak uruchomi mod_pythona (en).
Czy Django bdzie dziaa na hostingu dzielonym (jak TextDrive lub Dreamhost)?
Zobacz stron Django - przyjazne hostingi (en).
Uywanie Django
Dlaczego mam bd w imporcie DJANGO_SETTINGS_MODULE?
Upewnij si e:
Zmienna rodowiskowa DJANGO_SETTINGS_MODULE wskazuje na peny modu Pythona (np. mysite.settings). Sprawd czy modu znajduje si w sys.path (import mysite.settings powinno dziaa). Sprawd, czy modu nie zawiera bdw skadni (oczywiste). Jeeli uywasz mod_pythona, ale bez request handlera z Django, musisz obej bd mod_pythona zwizany z uywaniem SetEnv; zanim zaimportujesz cokolwiek z Django, musisz wykona nastpujc czynno: 54
os.environ.update(req.subprocess_env)
55
connection.queries dostpne jest tylko, jeeli DEBUG jest rwne True. To jest lista sownikw w kolejnoci wywoania zapytania. Kady sownik ma: ``sql`` -- Tre zapytania SQL ``time`` -- Jak dugo zajo wykonanie zapytania, w sekundach. connection.queries
zawiera wszystkie zapytania SQL INSERTy, UPDATEy, SELECTy, itd. Za kadym razem, gdy Twoja aplikacja wykonuje zapytanie do bazy, zapytanie zostanie zapamitane.
Jeeli wprowadz zmiany do modelu, to jak mog zrobi update bazy danych?
Jeeli nie jest dla Ciebie problemem wyczyszczenie danych, to narzdzie manage.py z Twojego projektu ma opcj resetowania SQL dla konkretnej aplikacji:
manage.py reset twoja_aplikacja
To polecenie usuwa wszystkie tabele skojarzone z twoja_aplikacja i tworzy je na nowo. Jeeli jednak nie chcesz usun danych, musisz rcznie wykona wyraenie ALTER TABLE na Twojej bazie danych. W taki sposb robilimy to zawsze, poniewa dziaanie na danych to delikatna operacja dlatego te w tym przypadku chcielimy unikn automatyzacji. Trwaj prace, aby doda funkcjonalno czciowej automatyzacji aktualizacji schematu bazy danych (przp. tum. zainteresuj si narzdziem dbmigration (en) dla Django`).
Jak doda specyficzne opcje dla bazy danych do wyraenia CREATE TABLE, takie jak okrelenie typu tabeli jako MyISAM?
Staramy si unika specjalnych przypadkw w kodzie Django, aby speni wszystkie specyficzne opcje baz danych takie jak typy tabel itd. Jeeli chciaby uywa jakichkolwiek z tych opcji, stwrz plik inicjujcy dane SQL (en), ktry zawiera wyraenie ALTER TABLE modyfikujce to, co potrzebujesz. Pliki inicjujce s wykonywane na bazie danych po wyraeniach CREATE TABLE. Na przykad, jeeli uywasz MySQLa i chciaby, aby Twoje tabele uyway typu MyISAM, stwrz plik inicjujcy dane i wstaw tam co takiego: 56
Jak opisano w dokumentacji, pliki inicjujce dane SQL (en), plik SQL moe zawiera dowolny kod SQL, tak wic moesz dokona dowolnych zmian, jakich potrzebujesz.
Panel administracyjny
Nie mog si zalogowa. Kiedy wprowadzam nazw uytkowanika oraz haso, pojawia si strona logowania bez adnych bdw.
Login cookie nie zosta poprawnie ustawiony, poniewa domena cookie wysana przez Django nie zgadza si z domen Twojej przegldarki. Sprbuj dwch rzeczy:
Ustaw SESSION_COOKIE_DOMAIN w pliku konfiguracyjnym, aby pasowao do Twojej domeny. Na przykad jeeli w przegldarce otwierasz adres http://www.mojserwis.pl/admin/, w ustawieniach Twojego projektu powiniene ustawi SESSION_COOKIE_DOMAIN = 'www.mojserwis.pl'. Niektre przegldarki (Firefox?) nie lubi akceptowa cookies z domen, ktre nie maj kropek w rodku. Jeeli uywasz panelu administracyjnego na localhost lub w innej domenie ktra nie ma kropek w nazwie, sprbuj uy localhost.localdomain lub 127.0.0.1 dla ustawienia SESSION_COOKIE_DOMAIN.
Nie mog si zalogowa. Kiedy wprowadzam nazw uytkownika oraz haso, pojawia strona logowania, z bdem Prosz wprowad poprawn nazw uytkownika i haso.
Jeeli jeste pewien, e Twoja nazwa uytkownika i haso s poprawne, upewnij si, e Twj uytkownik ma ustawione is_active oraz is_staff na True. Panel administracyjny pozwala na dostp tylko uytkownikom, ktrzy maj te dwa pola ustawione na True.
57
Jak mog zapobiec, aby cache middleware nie cacheowa panelu administracyjnego?
Ustaw CACHE_MIDDLEWARE_ANONYMOUS_ONLY na True. Zobacz dokumentacje cacheu, aby uzyska wicej informacji.
Jak automatycznie ustawi warto pola na uytkownika, ktry ostatnio edytowa obiekt w adminie?
W tym przypadku, Django nie ma oficjalnego waciwego sposobu. Jednak jest to funkcjonalno, o ktr prosi wielu ludzi, wic rozwaamy jak to zaimplementowa. Problem w tym, e nie chcemy czy warstwy modelu z warstw admina oraz warstw dania (aby pobra aktualnie zalogowanego uytkownika. Jest to do zawiy problem. Jedna osoba znalaza rozwizanie ktre nie wymaga zmian w kodzie rdowym Django (en), miej jednak na uwadze e jest to nieoficjalne rozwianie i nie ma gwarancji, e za jaki czas nie przestanie dziaa.
Jak ograniczy dostp w panelu administracyjnym, aby obiekty mogy by tylko edytowane przez uytkownikw ktrzy je stworzyli?
Zobacz odpowied na poprzednie pytanie.
Style CSS oraz obrazki pojawiaj si w adminie uywajc serwera developerskiego, ale nie wywietlaj si gdy uywam mod_pythona.
Zobacz serwowanie plikw admina (en) w dokumencie Jak uywa Django z mod_pythonem.
58
administracyjny jest zasilany przez Django, wic moesz napisa wasne widoki, ktre integruj si systemem autoryzacji, sprawdzaniem uprawnie oraz cokolwiek innego potrzebujesz. Jeeli chciaby zmieni wygld interfejsu admina, przeczytaj kolejn opowied.
Pisanie kodu
Jak mog zacz pisa kod do Django?
Dzikujemy e pytasz! Napisalimy cay dokument powicony odpowiedzi na te pytanie. Jest zatytuowany Contributing to Django (en).
Wrzuciem poprawk bdu w systemie ticetw kilka tygodni temu. Dlaczego ignorujecie moj poprawk?
Nie martw si: Nie ignorujemy Ci! Warto zrozumie rnic pomidzy ticket jest ignorowany a ticket nie zosta jeszcze rozpatrzony. System ticketw Django zawiera setki otwartych ticketw o rnym wpywie na ostateczn funkcjonalno. Deweloperzy Django musz je przejrze i okreli ich priorytet. Poza tym, jeeli Twoja proba o dan funkcjonalno nie ma szans na wczenie do Django, nie bdziemy jej ignorowa po prostu zamkniemy ticket. Wic jeeli Twj ticket jest cigle otwarty, to nie oznacza, e Ci ignorujemy, po prostu nie mielimy jeszcze czasu, aby mu si przyjrze.
59