Open Source

Twoja pierwsza aplikacja w Django, część 1

Uczmy się na przykładach.

W tym tutorialu przejdziemy przez kolejne kroki tworzenia prostego systemu ankiet.

Składa się on z dwóch części:

  • Publicznej - gdzie wyświetlane są ankiety i można na nie głosować.
  • Administracyjnej - która pozwala na dodawanie, edytowanie i usuwanie ankiet.

Zakładam, że posiadasz już zainstalowane Django. Możesz to sprawdzić uruchamiając interaktywny interpreter Pythona i wpisując import django. Jeśli to się powiedzie, bez żadnych komunikatów błędów, oznacza to że posiadasz poprawnie zainstalowane Django.

Gdzie szukać pomocy:

Jeśli masz problemy podczas przerabiania tego tutoriala, możesz napisać wiadomość na django-users lub dołączyć do kanału #django na serwerze irc.freenode.net gdzie spróbujemy Ci pomóc.

Tworzenie projektu

Jeśli to Twój pierwszy kontakt z Django, poświęć chwilę na początkową konfigurację. Oznacza to, że będziesz musiał wygenerować kawałek kodu, który będzie projektem Django — zbiorem ustawień dla instancji Django, włączając w to konfigurację połączenia z bazą danych, opcji specyficznych dla Django i Twojej aplikacji.

W linii poleceń, wykonaj komendę cd aby przejść do katalogu gdzie chciałbyś trzymać swój kod, następnie wpisz django-admin.py startproject mysite. Stworzysz w ten sposób katalog mysite w bieżącym katalogu.

Uprawnienia w Mac OS X

Jeśli używasz Mac OS X, możesz zobaczyć komunikat “permission denied” podczas próby wykonania django-admin.py startproject. Jest to spowodowane tym, że w systemach Uniksowych jak OS X, plik musi być oznaczony jako “wykonywalny” zanim może zostać uruchomiony jako program. Aby to poprawić, otwórz Terminal.app, przejdź (używając Komendy cd) do katalogu gdzie jest zainstalowany plik django-admin.py i wykonaj komendę chmod +x django-admin.py.

Note

Powinieneś unikać nazywania projektów nazwami wbudowanych w Pythona lub nazwami komponentów Django. W szczególności oznacza to unikanie nazw takich jak django (która będzie kolidować z samym Django) lub site (która spowoduje konflikt z wbudowanym w Pythona pakietem).

(Jeśli instalowałeś Django poprzez python setup.py, django-admin.py powinno znajdować się w twojej ścieżce systemowej. Jeśli tak nie jest, powinieneś ją znaleźć w site-packages/django/bin, gdzie site-packages jest katalogiem z instalacją Pythona. Rozważ możliwość utworzenia dowiązania symbolicznego do django-admin.py z jednego z folderów znajdujących się w Twojej ścieżce systemowej, np. z /usr/local/bin.)

Gdzie powinien znajdować się kod Django?

Jeśli w przeszłości programowałeś w PHP, najprawdopodobniej przywykłeś 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 pomysłem umiejscawianie jakiegokolwiek kodu Pythona wewnątrz document root, ponieważ stwarza to zagrożenie możliwości oglądania Twojego kodu przez odwiedzających. Nie jest do dobre ze względów bezpieczeństwa.

Umieść swój kod w którymkolwiek katalogu poza document root, w takim jak np. /home/mycode.

Zobaczmy zatem co utworzył nam startproject:

mysite/
    __init__.py
    manage.py
    settings.py
    urls.py
Te pliki to:
  • __init__.py: Pusty plik informujący Pythona o tym, że katalog nadrzędny powinien być traktowany jako pakiet Pythona (zobacz więcej na temat pakietów).
  • manage.py: Działające z linii poleceń narzędzie, które pozwala na interakcję z projektem Django na różne sposoby.
  • settings.py: Ustawienia/konfiguracja dla tego projektu Django.
  • urls.py: Deklaracja adresów URL dla tego projektu Django; “mapa serwisu” Twojej strony zbudowanej w oparciu o Django.

Serwer deweloperski

Sprawdźmy czy działa. Przejdź do katalogu mysite, o ile jeszcze w nim nie jesteś i uruchom polecenie python manage.py runserver. Powinieneś zobaczyć następujący tekst na wyjściu 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).

Właśnie wystartowałeś serwer deweloperski Django, lekki serwer www napisany w całości w Pythonie. Dołączyliśmy go do Django byś mógł rozwijać swój kod możliwie szybko, bez potrzeby konfiguracji serwera produkcyjnego — takiego jak Apache — do momentu, aż będziesz gotowy do wdrożenia produkcyjnego.

Nadszedł dobry moment by zauważyć: NIE UŻYWAJ tego serwera do niczego co choćby przypomina środowisko produkcyjne. Jest on przeznaczony jedynie do pomocy w procesie rozwijania własnego kodu (naszą pracą jest tworzenie frameworków sieciowych a nie serwerów www).

Teraz, kiedy serwer jest uruchomiony, odwiedź http://127.0.0.1:8000/ za pomocą swojej przeglądarki internetowej. Powinieneś zobaczyć stronę powitalną, w miłych, jasnoniebieskich pastelowych kolorach. To działa!

Zmiana portu

Domyślnie polecenie runserver uruchamia serwer deweloperski na porcie 8000. Jeśli chcesz zmienić port serwera, prześlij jego wartość jako argument przy wywołaniu z linii poleceń. Dla przykładu - to polecenie uruchamia serwer na porcie 8080:

python manage.py runserver 8080

Pełna dokumentacja dla serwera deweloperskiego znajduje się na stronie dokumentacji panelu admina.

Ustawienia bazy danych

Teraz możemy przejść do edycji settings.py. Jest to zwykły moduł Pythona zawierający zmienne reprezentujące ustawienia Django. Ustaw następujące parametry tak, aby odzwierciedlały konfigurację Twojej bazy danych:

  • DATABASE_ENGINE — ‘postgresql_psycopg2’, ‘mysql’ lub ‘sqlite3’. Inne backendy są również dostępne.
  • DATABASE_NAME — Nazwa Twojej bazy danych, bądź absolutna ścieżka do pliku bazy danych, jeśli używasz SQLite.
  • DATABASE_USER — Nazwa użytkownika uprawnionego do połączenia z bazą danych (nie używane w SQLite).
  • DATABASE_PASSWORD — Hasło dostępu do bazy danych (nie używane w SQLite).
  • DATABASE_HOST — Adres serwera bazy danych. Możesz zostawić puste jeśli serwer bazy danych znajduje się na tym samym komputerze co Twoja aplikacja (nie używane w SQLite).

Uwaga

Jeśli używasz MySQL lub PostgreSQL, upewnij się że stworzyłeś potrzebną bazę danych. Możesz to wykonać poleceniem “CREATE DATABASE database_name;” z wnętrza powłoki trybu aktywnego swojej bazy danych.

Edytując plik settings.py zwróć uwagę na ustawienia INSTALLED_APPS znajdujące się na samym dole. Ta zmienna przechowuje nazwy wszystkich aplikacji Django, które są aktywowane w bieżącej instancji Django. Aplikacje mogą być używane w wielu projektach - możesz tworzyć z nich pakiety i rozpowszechniać je aby inni mogli ich używać w swoich projektach.

Domyślnie INSTALLED_APPS zawiera następujące aplikacje, wszystkie pochodzące od Django:

  • django.contrib.auth — System uwierzytelniania.
  • django.contrib.contenttypes — Framework do trzymania typów modeli.
  • django.contrib.sessions — Framework sesji.
  • django.contrib.sites — Framework do zarządzania wieloma stronami w jednej instalacji Django.

Te aplikacje są dołączane domyślnie w ramach wygody dla powszechnych przypadków użycia.

Każda z tych aplikacji używa co najmniej jednej tabeli w bazie danych, które należy utworzyć przed ich użyciem. By to zrobić, wywołaj następujące polecenie:

python manage.py syncdb

Komenda syncdb patrzy na ustawienia INSTALLED_APPS i tworzy wszystkie potrzebne tabele w bazie z uwzględnieniem ustawień odnośnie baz danych w Twoim pliku settings.py. Powinieneś zobaczyć informację o każdej utworzonej przez niego tabeli i otrzymać zapytanie o utworzenie konta superużytkownika dla systemu uwierzytelniania. Możesz śmiało na to się zgodzić.

Jeśli jesteś zainteresowany, uruchom klienta linii poleceń swojej bazy danych i wpisz \dt (PostgreSQL), SHOW TABLES; (MySQL) lub .schema (SQLite) celem wyświetlenia tabel utworzonych przez Django.

Dla minimalistów

Jak wcześniej wspomnieliśmy, domyślne aplikacje są dołączone dla najpowszechniejszych zastosowań, ale nie każdy ich potrzebuje. Jeśli nie potrzebujesz którejś lub wszystkich możesz zwyczajnie je za komentować lub usunąć odpowiadające 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.

Każda aplikacja, którą piszesz w Django, opiera się na pakietach Pythona, leżących gdzieś w Twojej ścieżce dostępu Pythona, co wynika z pewnych konwencji. Na szczęście Django zapewnia zestaw narzędzi, które automatycznie generują podstawową strukturę aplikacji, więc możesz skupić się raczej na pisaniu kodu zamiast na tworzeniu katalogów.

Projekty kontra aplikacje

Jaka jest różnica pomiędzy projektem a aplikacją? Aplikacja coś robi — jest nią np. system blogowy, rejestr danych publicznych lub prosta ankieta. Projekt jest kolekcją konfiguracji i aplikacji dla określonej strony www. Projekt może zawierać wiele aplikacji. Dana aplikacja może być w wielu projektach.

W tym tutorialu dla ułatwienia utworzymy aplikację ankiety w katalogu mysite. W konsekwencji aplikacja będzie połączona z projektem — to znaczy kod aplikacji ankiety będzie odnosił się do aplikacji mysite.polls. Dalej w tym tutorialu omówimy jak uniezależnić Twoją aplikację od dystrybucji.

Aby utworzyć aplikację, upewnij się że jesteś wewnątrz katalogu mysite i wprowadź następujące polecenie:

python manage.py startapp polls

To utworzy katalog polls, którego zawartość wygląda mniej więcej tak:

polls/
    __init__.py
    models.py
    views.py

Ta struktura katalogu będzie przechowywać kod źródłowy aplikacji ankiety.

Pierwszym krokiem w pisaniu aplikacji www korzystającej z bazy danych w Django jest zdefiniowanie modeli — układ w bazie danych z dodatkowymi metadanymi.

Filozofia

Model jest pojedynczym, definiującym źródłem na temat Twoich danych. Zawiera istotne pola i definiuje zachowania danych przez Ciebie przechowywanych. Django podąża 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 każda z odpowiedzi posiada pola: treść odpowiedzi (choice) i liczbę oddanych głosów (votes). Każda odpowiedź jest powiązana z konkretną sondą.

Te założenia są odwzorowane przez klasy napisane w Pythonie. Poddaj edycji plik polls/models.py aby wyglądał tak jak poniżej:

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()

Błędy spowodowane max_length

Jeśli Django wyrzuca komunikaty błędów mówiące że max_length nie jest poprawnym argumentem, najprawdopodobniej używasz starej wersji Django (ta wersja tutoriala została napisana dla najnowszej, rozwojowej wersji Django). Jeśli korzystasz z rozwojowej wersji Django z Subversion (zobacz dokumentację instalacyjną by uzyskać więcej informacji), nie powinieneś mieć z tym żadnych problemów.

Jeśli chcesz pozostać ze starszą wersją Django, będziesz musiał przejść do tutoriala dla Django 0.96, ponieważ ten tutorial omawia kilka właściwości które istnieją jedynie w wersji rozwojowej.

Kod jest samo wyjaśniający się. Każdy model jest reprezentowany przez podklasę, która dziedziczy z klasy django.core.meta.Model. Każdy model posiada pewną liczbę zmiennych, z których każda reprezentuje pole w bazie danych.

Każde pole jest reprezentowane jako instancja klasy meta.*Field — np. models.CharField dla pól tekstowych i models.DateTimeField` dla obiektów datetime. Fakt ten pozwala Django stwierdzić, jakiego typu dane są przechowywane przez każde z pól.

Nazwa każdej z instancji meta.*Field (np. question lub pub_date) jest nazwą pola, taką jakiej oczekuje komputer. Będziesz używać tych nazw w swoim kodzie, a Twoja baza danych będzie używać ich jako nazwy kolumn.

Możesz też użyć opcjonalnego parametru dla pola aby przypisać mu dowolną, przyjazną człowiekowi nazwę. Jest to używane podczas introspekcji różnych części Django, a także w dokumentacji. Jeżeli tego pola nie ma, Django będzie używać nazwy zmiennej. W naszym przykładzie zdefiniowaliśmy tylko jedną przyjazną dla użytkownika nazwę, dla pola Poll.pub_date. Dla wszystkich innych pól w tym modelu, nazwy zmiennych są wystarczająco czytelne dla człowieka.

Niektóre klasy Field wymagają podania pewnych atrybutów. Klasa CharField na przykład oczekuje parametru max_length. Jest on używany nie tylko przy tworzeniu struktury bazy danych, ale także podczas weryfikacji poprawności danych, o czym się niedługo sam przekonasz.

Na koniec zauważ, że zostały zdefiniowane także relacje między klasami za pomocą models.ForeignKey. To mówi Django o powiązaniach między każdą z odpowiedzi a konkretną sondą. Django obsługuje powiązania: wiele-do-jednego (many-to-one), wiele-do-wielu (many-to-many) i jeden-do-jednego (one-to-one).

Aktywacja modeli

Ta mała część kodu modelu dostarcza Django mnóstwa informacji. Z jego pomocą, Django może:

  • Stworzyć strukturę bazy danych (wygenerować kwerendy CREATE TABLE) dla tworzonej aplikacji.
  • Stworzyć API dostępu do bazy danych dla obiektów Poll i Choice.

Ale najpierw, musimy poinformować nasz projekt że aplikacja polls (sonda) została zainstalowana.

Filozofia

Aplikcje Django są wtyczkami (pluginami): możesz używać ich w wielu projektach, a także 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 wyglądać 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ć następujący ciąg 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ść wyjściowa będzie zależeć od bazy danych jakiej używasz.
  • Nazwy tabel są generowane automatycznie poprzez kombinację nazwy aplikacji (polls) i nazwy modelu zapisanej małymi literami — poll i choice (możesz zmienić to domyślne zachowanie).
  • Klucze główne (ID) są dodawane automatycznie (aczkolwiek możesz to zmienić).
  • Django dodaje końcówkę "_id" do zazw pól kluczy obcych (ForeignKey). Również to zachowanie możesz jednak zmienić.
  • Powiązania z użyciem kluczy obcych są tworzone poprzez deklarację REFERENCES.
  • To jest ściśle powiązane z bazą danych której używasz, więc 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 zależności od bazy danych używa się pojedynczych bądź podwójnych cudzysłowów. Autor tego wprowadzenia używa PostgreSQL, tak więc przykłady są napisane dla tej bazy.
  • Komenda sql nie wykonuje zapytań SQL na twoje bazie danych - jedynie drukuje je na ekranie byś mógł zobaczyć jaki SQL Django uważa na wymagany. Jeśli chcesz, możesz skopiować i wkleić ten fragment kodu SQL na wejście trybu interaktywnego swojej bazy danych. Jednakże, jak wkrótce zobaczymy, Django zapewnia prostą metodę zatwierdzania tego SQL-a do Twojej bazy danych.
Jeśli jesteś zainteresowany, możesz także uruchomić poniższe komendy:
  • python manage.py validate — Sprawdza Twój model w poszukiwaniu jakichkolwiek błędów konstrukcyjnych.
  • python manage.py sqlcustom polls — Wypisuje wszelkie własne zapytania SQL (takie jak modyfikacja tabeli lub ograniczenia (ang. constraints)) które są definiowane przez aplikacje.
  • python manage.py sqlclear polls — Wypisuje wymagane wyrażenia DROP TABLE dla tej aplikacji, biorąc pod uwagę aktualnie istniejące tabele w Twojej bazie danych (jeśli takowe istnieją).
  • python manage.py sqlindexes polls — Wypisuje wyrażenie CREATE INDEX dla tej aplikacji.
  • python manage.py sqlall polls — Kombinacja wszystkich wyjściowych wartości wyrażeń SQL z poleceń ‘sql’, ‘sqlcustom’ i ‘sqlindexes’.

Przejrzenie wyników powyższych komend pomoże 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 które nie istnieją aktualnie w Twojej bazie danych. Polecenie to tworzy wszystkie tabele, inicjalizuje dane i indeksuje dla każdej aplikacji którą dodałeś do projektu od momentu ostatniego uruchomienia komendy syncdb. syncdb może być wykonywane przez Ciebie tak często, jak Ci się to podoba tworząc tabele tylko wtedy, gdy nie istnieją.

Przeczytaj dokumentację django-admin.py dowiedzieć się o pełnych możliwościach manage.py.

Zabawy z API

Przejdź teraz do interaktywnej powłoki Pythona i poćwicz nieco wykorzystanie API dostarczone przez Django. By uruchomić powłokę Pythona uruchom komendę:

python manage.py shell

Używamy jej zamiast zwykłego polecenia “python”, ponieważ manage.py ustawia środowisko projektu za nas. “Ustawienie środowiska” polega na dwóch rzeczach:

  • Dodaniu mysite do sys.path. Dla elastyczności, kilka fragmentów Django odnosi się do projektów w Pythonie stosując notację z kropką (np. 'mysite.polls.models'). W związku z tym pakiet mysite musi znajdować się w system.path.

    Niedawno widzieliśmy przykład takiego użycia: INSTALLED APPS przechowuje listę pakietów we wspomnianej notacji z kropką.

  • Ustawieniu zmiennej DJANGO_SETTINGS_MODULE, która zapewnia Django ścieżkę do Twojego pliku settings.py.

Praca bez wykorzystania manage.py

Jeśli nie chcesz używać manage.py nie ma problemu. Po prostu upewnij się, że mysite na głównym poziomie ścieżki dostępu Pythona (import mysite działa) i ustawia zmiennej środowiskowej DJANGO_SETTINGS_MODULE wartość mysite.settings.

W celu uzyskania większej ilości informacji zobacz dokumentację django-admin.py.

Gdy już będziesz w shellu zbadaj API bazy danych:

# Zaimportuj modele klas które uprzednio napisaliśmy.
>>> from mysite.polls.models import Poll, Choice

# Na chwilę obecną nie ma w systemie żadnych ankiet.
>>> Poll.objects.all()
[]

# Utwórz nową ankietę Poll.
>>> import datetime
>>> p = Poll(question="Jak leci?", pub_date=datetime.datetime.now())

# Zapisz obiekt w bazie danych. Musisz wywołać metodę save() jawnie.
>>> p.save()

# Teraz ma on swoje ID. Zauważ, że może ono mieć wartość "1L" zamiast "1",
# w zależności od tego jakiej bazy danych używasz. To jednak drobnostka;
# oznacza to jedynie tyle, że Twoja baza danych woli zwracać typ integer
# jako obiekt long integer Pythona.
>>> p.id
1

# Dostęp do kolumn następuje przez atrybuty Pythona.
>>> p.question
"Jak leci?"
>>> p.pub_date
datetime.datetime(2007, 7, 15, 12, 00, 53)

# Pozmieniaj wartości zmieniając atrybuty i wywołując metodę save().
>>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0)
>>> p.save()

# objects.all() wyświetla wszystkie ankiety w bazie danych.
>>> Poll.objects.all()
[<Poll: Poll object>]

Chwila. <Poll: Poll object> jest wyświetlany w formie mało pomocnej reprezentacji tego obiektu. Naprawmy to poprzez edycję modelu sondy (opisanego w pliku polls/models.py) i przeciążeniu 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 działać

Jeśli dodałeś do swoich modeli metodę __unicode__() i nie widzisz żadnej zmiany w tym jak są reprezentowane, najprawdopodobniej używasz starej wersji Django (ta wersja tutoriala została napisana dla najnowszej, rozwojowej wersji Django). Jeśli korzystasz z rozwojowej wersji Django z Subversion (zobacz dokumentację instalacyjną by uzyskać więcej informacji), nie powinieneś mieć z tym żadnych problemów.

Jeśli chcesz pozostać ze starszą wersją Django, będziesz musiał przejść do tutoriala dla Django 0.96, ponieważ ten tutorial omawia kilka właściwości które istnieją jedynie w wersji rozwojowej.

Przeciążanie metody __unicode__() w modelach jest ważne nie tylko z powodu zwiększenia czytelności przy używaniu powłoki interaktywnej, ale także ponieważ reprezentacje obiektów są używane przez Django w automatycznie generowanym panelu administracyjnym.

Dlaczego __unicode__() a nie __str__()?

Jeśli jesteś obeznany z Pythonem, możesz mieć nawyk dodawania do swoich klas metody __str__() a nie __unicode__(). Używamy __unicode__() ponieważ modele Django mają domyślnie do czynienia z unikodem. Wszelkie dane trzymane w twojej bazie danych są konwertowane do unikodu zaraz po ich wyciągnięciu.

Domyślna metoda __str__() modeli Django wywołuje __unicode__() i konwertuje rezultat na bytestringa UTF-8. Oznacza to, że unicode(p) zwraca ciąg znaków Unicode, zaś str(p) zwraca normalny ciąg znaków zakodowany jako UTF-8.

Jeśli wszystko co zostało wcześniej napisane nie ma dla Ciebie większego sensu, po prostu pamiętaj dodać do swoich modeli metodę __unicode__(). Z odrobiną szczęścia wszystko powinno po prostu działać.

Zwróć uwagę, że są to zwykłe metody Pythona. Dla celów demonstracyjnych dodajmy własną metodę:

import datetime
# ...
class Poll(models.Model):
    # ...
    def was_published_today(self):
        return self.pub_date.date() == datetime.date.today()

Zauważ, że dodatkowa linia import datetime odnosi się do standardowego modułu Pythona datetime.

Przejdźmy z powrotem do interaktywnej powłoki Pythona uruchamiając ponownie python manage.py shell:

>>> from mysite.polls.models import Poll, Choice

# Upewnij się że dodana przez nas metoda __unicode__() działa.
>>> Poll.objects.all()
[<Poll: Jak leci?>]

# Django zapewnia bogate API bazy danych, które w całości napędzane jest
# nazywanymi argumentami
>>> Poll.objects.filter(id=1)
[<Poll: Jak leci?>]
>>> Poll.objects.filter(question__startswith='Jak')
[<Poll: Jak leci?>]

# Pobierz ankietę, której rok wynosi 2007. Oczywiście jeśli wcześniej
# w trakcie tego tutoriala wybrałeś 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 wartości klucza głównego jest
# najczęściej stosowanym przypadkiem, dlatego Django zapewnia odpowiednią
# metodę.
# Poniższe jest identyczne z Poll.objects.get(id=1).
>>> Poll.objects.get(pk=1)
<Poll: Jak leci?>

# Upewnij się że zdefiniowana przez Ciebie metoda działa.
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_today()
False

# Dołącz do ankiety (Poll) kilka odpowiedzi (Choices). Wywołanie
# konstruktora tworzy nowy obiekt odpowiedzi, wykonuje polecenie INSERT,
# dodaje odpowiedź do listy dostępnych 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 zapewniające dostęp do związanych
# z nimi obiektami ankiety (Polls).
>>> c.poll
<Poll: Jak leci?>

# I odwrotnie: obiekty Poll posiadają dostęp do obiektów Choice.
>>> p.choice_set.all()
[<Choice: Specjalnie nic nowego>, <Choice: Ciurkiem>, <Choice: Znowu programuję>]
>>> p.choice_set.count()
3

# Omawiane API automatycznie podąża za relacjami tak daleko jak tego
# potrzebujesz. Użyj podwójnego podkreślnika by oddzielić powiązania.
# Działa to dla tylu poziomów głębokości dla ilu chcesz - nie ma limitu.
# Znajdź wszystkie Odpowiedzi (Choices) dla każdej 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. Użyj delete() aby tego dokonać.
>>> c = p.choice_set.filter(choice__startswith='Znowu program')
>>> c.delete()

By uzyskać więcej informacji na temat API do baz danych zobacz dokumentację API do baz danych

Gdy już będziesz czuł się komfortowo używając wspomnianego wcześniej API, przeczytaj część 2 tego tutoriala aby dodać automatyczny panel admina.

Pytania/Wsparcie

Jeżeli zauważyłeś błędy w tłumaczeniu dokumentacji proszę zgłoś je nam.