UPDATE: aktualna wersja tłumaczenia znajduje się na serwerze django.pl: http://django.pl/documentation/tutorial01/

Tworzenie pierwszej aplikacji Django, część 1

Autor oryginału: Adrian Holovaty <holovaty {} gmail // com>
Adres oryginału: www.djangoproject.com/documentation/tutorial1
Tłumaczenie: Marcin Sztolcman <marcin {} urzenia // net>

Będziemy uczyć się na przykładzie.

Czytając tutorial, będziesz tworzyć prostą aplikację internetową: sondę.

Aplikacja składać się będzie z dwóch części:

  • publicznej – tutaj użytkownik będzie mógł oddawać głos i przeglądać wyniki;
  • administracyjnej – pozwalającej na dodawanie, edycję oraz usuwanie sond osobom uprawnionym.

Zakładam tutaj, że posiadasz już poprawnie zainstalowane Django.

Początek

Jeśli jeszcze nie używałeś Django, musisz najpierw wykonać pewne kroki początkowe.

Uruchom polecenie: django-admin.py startproject myproject. Polecenie to stworzy katalog myproject w katalogu w którym obecnie się znajdujesz.

Katalog zawierający aplikację django-admin.py powinien być wymieniony w Twojej ścieżce dostępu jeżeli instalowałeś Django poprzez narzędzie setup.py. Jeżeli nie ma go w Twojej ścieżce dostępu, możesz go znaleźć w katalogu site-packages/django/bin; najprościej jest utworzyć dowiązanie symboliczne do któregoś katalogu znajdującego się w Twojej ścieżce dostępu, np /usr/local/bin.

Projekt jest to zbiór ustawień dla instancji Django – zawierający konfigurację bazy danych, a także ustawienia Django i poszczególnych aplikacji. Spójrzmy na strukturę katalogów, jaką utworzyło polecenie startproject:

myproject/
    __init__.py
    apps/
        __init__.py
    settings.py
    urls.py

Najpierw wyedytuj plik myproject/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’, ‘mysql’ lub ’sqlite3′;
  • DATABASE_NAME – Nazwa Twojej bazy danych, lub absolutna ścieżka do pliku bazy 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;“.

Następnym krokiem jaki musisz wykonać, jest umieszczenie katalogu myproject w ścieżce dostępu Pythona. Aby to zrobić skopiuj katalog myproject do podkatalogu Pythona site-packages, lub zmieniając zmienną środowiskową PYTHONPATH. Zajrzyj do dokumentacji Pythona aby uzyskać więcej informacji. Zauważ że jeśli zdecydowałeś się ustawić zmienną środowiskową PYTHONPATH, to musisz ją ustawić tak aby wskazywała na rodzica katalogu myproject (możesz to sprawdzić wpisując “import myproject” w powłoce interaktywnej pythona).

Wykonaj teraz komendę:

django-admin.py init --settings=myproject.setting

Narzędzie django-admin.py musi wiedzieć, jakiego modułu ustawień chcesz używać. Powyżej w linii komend dodaliśmy opcję “settings” do wywołania programu django-admin.py, ale to jest nieco męczące. Jeśli chcesz uniknąć wpisywania tego za każdym razem, możesz ustawić zmienną środowiskową DJANGO_SETTINGS_MODULE. Tutaj masz sposób jak to wykonać korzystjąc z powłoki Bash na Uniksie:

export DJANGO_SETTINGS_MODULE=myproject.settings

Jeśli korzystasz z Windowsa, możesz użyć polecenia set:

set DJANGO_SETTINGS_MODULE=myproject.settings

Jeżeli po uruchomieniu programu django-admin.py init nie zostały wyświetlone żadne błędy, wtedu możesz spokojnie przyjąć, ze wszystko działa. Powyższa komenda tworzy w Twojej bazie danych główne tabele używane przez Django. Możesz także uruchomić klienta swojej bazy danych, i wykonać tam \dt (dla PostgreSQL), SHOW TABLES (MySQL) lub .schema (sqlite) aby sprawdzić jakie tabele zostały utworzone.

Tworzenie modelu

Teraz, kiedy już utworzyłeś swoje środowisko pracy (projekt), możesz rozpocząć swoją pracę (już więcej nie będziesz musiał wykonywać tych nudnych administracyjnych czynności).

Każda aplikacja pisana w Django – jak np. blog lub sonda – istnieje jako zestaw modułów Pythona w jego ścieżce dostępu. Django dostarcza narzędzie które potrafi zautomatyzować tworzenie podstawowej struktury aplikacji, dzięki czemu możesz skoncentrować się na pisaniu kodu niż budowaniu drzewa katalogów.

W tym tutorialu, dla uproszczenia stworzymy naszą sondę w katalogu myproject/apps. W konsekwencji aplikacja będzie dołączona do projektu – kod Pythona z sondą będzie odwoływał się do myproject.apps.polls. Później przedyskutujemy odłączenie aplikacji od projektu dla celów dystrybucyjnych.

Aby stworzyć strukturę katalogów aplikacji, przejdź do katalogu myproject/apps i wykonaj komendę:

django-admin.py startap polls

(od teraz w tutorialu będziemy opuszczać parametr settings polecenia django-admin.py zakładając, że albo ustawiłeś sobie zmienną środowiskową DJANGO_SETTINGS_MODULE, albo będziesz samodzielnie dodawał parametr --settings=myproject.settings podczas wywołania django-admin.py).

Mamy utworzone takie drzewo katalogów:

polls/
    __init__.py
    models/
        __init__.py
        polls.py
    views.py

Te katalogi są “domem” dla Twojej sondy.

Pierwszym krokiem w tworzeniu aplikacji Django jest zdefiniowanie modeli – czyli ustalenie struktury bazy danych z dodatkowymi metadanymi.

Założenia

Model jest pojedynczym, kompletnym źródłem informacji o Twoich danych. Zawiera informacje o polach i zachowaniach danych które przechowujesz. Django podąża za wytycznymi z DRY Principle. 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/polls.py żeby wyglądał tak jak poniżej:

from django.core import meta

class Poll(meta.Model):
    question = meta.CharField(maxlength=200)
    pub_date = meta.DateTimeField('date published')

class Choice(meta.Model):
    poll = meta.ForeignKey(Poll)
    choice = meta.CharField(maxlength=200)
    votes = meta.IntegerField()

Kod jest samowyjaś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 przez instancję klasy meta.*Field – na przykład meta.CharField dla pól znakowych i meta.DateTimeField dla dat. Dzięki temu Django wie, jakiego typu dane są tam przechowywane.

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ć opcjnalnego 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 meta.*Field wymagają podania pewnych atrybutów. Klasa meta.CharField na przykład oczekuje parametru maxlength. Jest on używany nie tylko przy tworzeniu struktury bazy danych, ale także podczas walidacji, o czym się niedługo sam przekonasz.

Na koniec zauważ że zostały zdefiniowane także relacje między klasami za pomocą meta.ForeigKey. 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 modelu

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 założona.

Założenia

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 myproject/settings.py, i dopisz do INSTALLED_APPS “myproject.apps.polls”. Teraz powinno to wyglądać tak:

INSTALLED_APPS = (
    'myproject.apps.polls',
)

Nie zapomnij o kończącym przecinku – jest to jedna z reguł Pythona odnośnie jednowartościowych tupli (krotek).

Od teraz Django wie już, że myproject zawiera aplikację polls. Teraz wykonaj inną komendę:

django-admin.py sql polls

Zwróć uwagę, że nie ma znaczenia w jakim katalogu jesteś kiedy wykonujesz tą komendą.

Treaz powinieneś zobaczyć następujący ciąg poleceń CREATE TABLE dla Twojej sondy:

BEGIN;
CREATE TABLE polls_polls (
  id serial NOT NULL PRIMARY KEY,
  question varchar(200) NOT NULL,
  pub_date timestamp with time zone NOT NULL
);
CREATE TABLE polls_choices (
  id serial NOT NULL PRIMARY KEY,
  poll_id integer NOT NULL REFERENCES polls_polls (id),
  choice varchar(200) NOT NULL,
  votes integer NOT NULL
);
COMMIT;

Zauważ że:

  • nazwy tabel są automatycznie generowane poprzez kombinację nazwy aplikacji (polls) i nazwą obiektu (poll i choice) w liczbie mnogiej (możesz zmienić to domyślne zachowanie);
  • klucze Primary (ID) są dodawane automatycznie (aczkolwiek możesz to także zmienić);
  • Django dodaje końcówkę _id do nazw pól kluczy obcych (Foreign Key). 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. Autor tego wprowadzenia używa PostgreSQL, tak więc przykłady są napisane dla tej bazy.

Możesz też, jeśli chcesz, wykonać następujące komendy:

  • django-admin.py sqlinitialdata polls – wyświetla kwerendy SQL potrzebne do wstawienia do bazy odpowiednich danych potrzebnych do zainicjowania danej aplikacji (w tym wypadku sondy) we framework-u;
  • django-admin.py sqlclear polls – zwraca kwerendy potrzebne do usunięcia z bazy danych wszystkich informacji o naszej aplikacji;
  • django-admin.py sqlindexes polls – pokazuje kwerendy potrzebne do utworzenia indeksów dla naszej aplikacji;
  • django-admin.py sqlall polls – to samo co polecenia sql i sqlinitialdata razem.

Przejrzenie wyników powyższych komend pomoże Ci zrozumieć, co się dzieje “pod podszewką” Django.

Teraz wykonaj następującą komende, aby stworzyć odpowiednie tabele dla sondy:

django-admin.py install polls

Poza sceną, powyższa komenda pobierze kwerendy z django-admin.py sqlall polls i wykona w bazie danych wskazanej przez plik ustawień Django.

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

Poznajemy API Django

Najpierw, upewnij się że ustawiłeś zmienną środowiskową DJANGO_SETTINGS_MODULE (co opisywaliśmy wcześniej), a następnie otwórz powłokę interaktywną Pythona aby poznać API które dostarcza Django:

# Moduły są dynamicznie tworzone poprzez django.models.
# Ich nazwy są generowane poprzez utworzenie liczby mnogiej
# (jęz. angielskiego) z nazwy klasy z której został utworzony
# model.
>>> from django.models.polls import polls, choices

# Jeszcze nie ma w systemie żadnych sond
>>> polls.get_list()
[]

# Tworzymy nową sondę
>>> from datetime import datetime
>>> p = polls.Poll(question="What's up?", \
    pub_date=datetime.now())

# Zapisujemy obiekt w bazie danych poprzez wywołanie
# metody save().
>>> p.save()

# Teraz nasz obiekt posiada identyfikator ID.
>>> p.id
1

# Dzięki atrybutom obiektu mamy dostęp do zawartości
# poszczególnych kolumn w bazie danych.
>>> p.question
"What's up?"
>>> p.pub_date
datetime.datetime(2005, 7, 15, 12, 00, 53)

# Zmiany zawartości poszczególnych pól wykomujemy poprzez
# zmianę zawartości atrybutów obiektu, a następnie wywołaniu
# metody save().
>>> p.pub_date = datetime(2005, 4, 1, 0, 0)
>>> p.save()

# Metoda get_list() wyświetla wszystkie sondy z bazy danych.
>>> polls.get_list()
[<Poll object>]

Chwila. Obiekt Poll jest wyświetlany jako reprezentacja tego obiektu. Naprawmy to poprzez edycję modelu sondy (opisanego w pliku polls/models/polls.py) i przeciążeniu metody __repr__() w klasach Poll i Choice:

class Poll(meta.Model):
    # ...
    def __repr__(self):
        return self.question

class Choice(meta.Model):
    # ...
    def __repr__(self):
        return self.choice

Przeciążanie metody __repr__() w modelach jest ważne nie tylko dla 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.

Zauważ, że to są zwykłe metody Pythona. Dla demonstracji można dodać własną metodę:

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

Zwróć uwagę, że nie potrzebujesz instrukcji import datetime. Każda metoda ma dostęp do najczęściej używanych zmiennych, włączając w to moduł datetime z biblioteki standardowej Pythona.

Wróćmy teraz do powłoki Pythona:

>>> from django.models.polls import polls, choices
# Sprawdźmy czy metoda __repr__() działa jak należy
>>> polls.get_list()
[What's up?]

# Django dostarcza bogaty wybór metod do wyszukiwania
# danych przy pomocy argumentów kluczowych
>>> polls.get_object(id__exact=1)
What's up?
>>> polls.get_object(question__startswith='What')
What's up?
>>> polls.get_object(pub_date__year=2005)
What's up?
>>> polls.get_object(id__exact=2)
Traceback (most recent call last):
    ...
PollDoesNotExist: Poll does not exist for {'id__exact': 2}
>>> polls.get_list(question__startswith='What')
[What's up?]

# Najczęściej wykonywane jest wyszukiwanie po kluczu głównym
# (primary key), więc Django dostarcza skrót do tego typu
# wyszukiwania.
# Następująca instrukcja zwraca taki sam rezultat jak
# polls.get_object(id__exact=1).
>>> polls.get_object(pk=1)
What's up?

# Sprawdźmy czy działa dodana przez nas metoda:
>>> p = polls.get_object(pk=1)
>>> p.was_published_today()
False

# Dodajmy naszej sondzie kilka możliwych odpowiedzi (Choice).
# Każda z tych metod wywołuje kwerende INSERT oraz zwraca
# nowy obiekt Choice.
>>> p = polls.get_object(pk=1)
>>> p.add_choice(choice='Not much', votes=0)
Not much
>>> p.add_choice(choice='The sky', votes=0)
The sky
>>> c = p.add_choice(choice='Just hacking again', votes=0)

# Obiekt Choice posiada API dostępu do sondy (Poll) z którą
# jest powiązany
>>> c.get_poll()
What's up?

# I odwrotnie: obiekt sondy (Poll) posiada dostęp do
# obiektów odpowiedzi (Choice).
>>> p.get_choice_list()
[Not much, The sky, Just hacking again]
>>> p.get_choice_count()
3

# API automatycznie podąża za dowiązaniami tak głęboko, jak
# tylko tego potrzebujesz.
# Do rozdzielenia relacji używaj podwójnych podkreślników.
# Ten rodzaj dowiązań działa dla dowolnego poziomu zagłębień.
# Nie ma żadnych ograniczeń.
# Wyszukaj teraz wszystkie opcje dla każdej z sond której data
# publikacji (pub_date) była w 2005 r.
>>> choices.get_list(poll__pub_date__year=2005)
[Not much, The sky, Just hacking again]

# Do usunięcia jednej z odpowiedzi użyjemy metody delete()
>>> c = p.get_choice(choice__startswith='Just hacking')
>>> c.delete()

Aby poznać pełne API dostępu do bazy danych, zajrzyj do Database API reference.

Kiedy poznasz już bardzo dobrze powyższe API, przystąp do drugiej części kursu aby uruchomić automatyczny panel administracyjny Django.


Liczba komentarzy: 4

  1. 1 Była sobota, 31 Marzec 2007 roku gdy o godzinie 05:56 przyszedł myGeeBlog » Blog Archive » [art]Django tutorial, część 2 i stwierdził:

    [...] część tutoriala zaczyna się w miejscu, w którym skończyła się część pierwsza. Będziemy kontynuować budowę aplikacji webowej – sondy – i skupimy się na automatycznie [...]

  2. 2 Był wtorek, 25 Wrzesień 2007 roku gdy o godzinie 10:21 przyszedł myGeeBlog » Blog Archive » Django tutorial, część 1 i stwierdził:

    [...] Acha, zapomniałbym. Tutorial znajduje się pod tym adresem: urzenia.net/250/django-tutorial-czesc-1. [...]

  3. 3 Był wtorek, 25 Wrzesień 2007 roku gdy o godzinie 11:03 przyszedł myGeeBlog » Blog Archive » [art]Django tutorial, część 3 i stwierdził:

    [...] Część 1 [...]

  4. 4 Była sobota, 06 Marzec 2010 roku gdy o godzinie 11:39 przyszedł myGeeBlog » Blog Archive » Znów ten tutorial do Django… i stwierdził:

    [...] część 1 [...]

A Ty? Co o tym myślisz?

Możesz używać w komentarzach następujących znaczników:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Sblam! Antyspam