Open Source

Django w pigułce

Ponieważ Django powstawało w środowisku dziennikarskim, gdzie szybkość ma niebywałe znaczenie, zostało tak zaprojektowane, by móc szybko i łatwo wykonywać typowe zadania związane z tworzeniem stron internetowych. Oto krótki i nieformalny opis tego, jak napisać w Django aplikację wykorzystującą bazę danych do przechowywania informacji.

Celem tego dokumentu jest przedstawienie wystarczającego opisu technicznego, by zrozumieć, jak działa Django, ale nie jest to ćwiczenie ani opis poszczególnych funkcji. Zajrzyj do naszej szczegółowej dokumentacji Django, jeśli stwierdzisz, że chcesz zacząć nowy projekt.

Zaprojektuj swój model

Choć można używać Django bez bazy danych, dostarczamy je wraz z systemem ORM (odwzorowanie relacyjno-obiektowe). Za pomocą ORM możesz zdefiniować tabele w bazie danych oraz pracować na nich — pisząc i operując na klasach w Pythonie.

Składnia danych modelu zapewnia wiele różnorodnych sposobów przedstawiania modeli — jak do tej pory udawało jej się przez dwa lata rozwiązywać problemy ze schematem bazy danych. Oto krótki przykład:

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

    def __unicode__(self):
        return self.full_name

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

    def __unicode__(self):
        return self.headline

Instalacja modelu

Skorzystaj z narzędzia administracyjnego z wiersza poleceń, by automatycznie utworzyć tabele bazy danych:

manage.py syncdb

Polecenie syncdb analizuje wszystkie dostępne modele i tworzy te tabele bazy danych, które jeszcze w niej nie istnieją.

Skorzystaj z dostępnego API

Za darmo otrzymujesz bogaty interfejs programistyczny w Pythonie zapewniający dostęp do danych. API powstaje w locie, nie jest potrzebna żadna generacja kodu:

>>> from mysite.models import Reporter, Article

# W systemie nie ma jeszcze żadnych reporterów.
>>> Reporter.objects.all()
[]

# Utwórz nowego reportera (obiekt klasy Reporter).
>>> r = Reporter(full_name='Jan Kowalski')

# Zapisz obiekt w bazie danych. Musisz jawnie wywołać 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 udostępnia 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}

# Utwórz 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 artykułu umożliwia łatwy dostęp do powiązanego z nim obiektu reportera.
>>> r = a.reporter
>>> r.full_name
'Jan Kowalski'

# I odwrotnie:
# Obiekt reportera umożliwia łatwy dostęp do powiązanych z nim artykułów.
>>> r.article_set.all()
[Django jest super]

# Interfejs automatycznie wykorzystuje związki tak daleko, jak to będzie
# potrzebne, stosując złączenia bazodanowe (Django doda je automatycznie).
# Przedstawiony przykład znajduje wszystkie artykuły reportera, którego imię
# zaczyna się na "Jan".
>>> Article.objects.filter(reporter__full_name__startswith="Jan")
[Django jest super]

# Zmień obiekt, modyfikując jego atrybuty i wywołując metodę save().
>>> r.full_name = 'Piotr Nowak'
>>> r.save()

# Usuń obiekt metodą delete().
>>> r.delete()

Interfejs administracyjny: to nie tylko fundamenty — to cały dom

Po zdefiniowaniu modeli, Django potrafi automatycznie stworzyć profesjonalny, gotowy do wykorzystania w produkcji interfejs administracyjny — witrynę, która umożliwia uwierzytelnionym osobom dodawać, edytować i usuwać obiekty. Aby włączyć interfejs, wystarczy dodać do kodu modelu jeden dodatkowy wiersz:

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

Filozofia jest następująca — Ty, Twój klient lub zespół redakcyjny edytujecie dane witryny. Nie chcesz więc poświęcać czasu na tworzenie osobnych interfejsów administracyjnych tylko do zarządzania zawartością.

W Django bardzo często zdarza się, że modele powstają bardzo szybko wraz z włączonym systemem administracyjnym, by zespół redakcyjny (lub klienci) mogli zacząć wypełniać dane. Programiści i projektanci mogą się w tym czasie zająć utworzeniem publicznie dostępnej części interfejsu.

Zaprojektuj adresy URL

Czysty, elegancki wygląd adresów URL to bardzo ważny szczegół w wysokiej jakości aplikacjach WWW. Django zachęca do stosowania ładnych adresów URL, które nie kończą się brzydkimi rozszerzeniami typu .php lub .asp.

Aby zaprojektować adresy URL dla aplikacji, tworzymy moduł Pythona nazywany URLconf. Stanowi on niejako spis zawartości aplikacji, zapewniają proste odwzorowanie między wzorcami URL i funkcjami Pythona. URLconf zapewnia również bardzo dobre oddzielenie adresów URL od głównej logiki aplikacji.

Poniżej znajduje się przykładowy plik URLconf dla przedstawionego wcześniej przykładu z Reporter i Article:

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 pasującego wyrażenia regularnego, a następnie wywołanie odpowiadającej mu funkcji widoku (ang. view). Wyrażenia regularne stosują nawiasy do “wyłapania” wartości z adresów URL. Gdy użytkownik wysyła żądanie pobrania strony, Django przechodzi po kolei przez każdy z wzorców i zatrzymuje się na pierwszym, który odpowiada żądanemu adresowi URL. (Jeśli dopasowania nie uda się znaleźć, Django wywołuje specjalny widok dla błędu 404). Rozwiązanie to jest wyjątkowo szybkie, ponieważ Django kompiluje wyrażenia regularne w trakcie uruchamiania aplikacji serwerowej.

Gdy Django znajdzie pasujące wyrażenie regularne, importuje i wywołuje wskazany widok, który jest zwykłą Pythonową funkcją. Do każdego widoku trafia obiekt żądania — zawierający metadane żądania — oraz wartości zebrane podczas analizy wyrażenia regularnego.

Jeśli na przykład użytkownik zażąda adresu URL “/artykuly/2005/05/39323/”, Django wywoła funkcję mysite.views.article_detail(request, '2005', '05', '39323').

Napisz widoki

Każdy widok odpowiada za wykonanie jednej z dwóch rzeczy: zwrócenie obiektu HttpResponse zawierającego zawartość żądanej strony lub zgłoszenie wyjątku takiego jak Http404. To, co się będzie działo w jego wnętrzu, zależy od Ciebie.

Ogólnie rzecz biorąc widok pobiera dane zgodnie z przekazanymi parametrami, wczytuje szablon i renderuje go, wykorzystując pobrane dane. Oto przykład widoku year_archive dla wcześniejszego przykładu 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}
                             )

Przykład wykorzystuje system szablonów Django, który ma kilka potężnych funkcji, ale jednocześnie pozostaje na tyle prosty, by mógł być wykorzystywany przez osoby niezaznajomione z programowaniem.

Zaprojektuj szablony

Przedstawiony powyżej kod wczytuje szablon news/year_archive.html.

Django wykorzystuje ścieżkę wyszukiwania szablonów, która umożliwia minimalizację redundancji między szablonami. W pliku ustawień określa się listę folderów, które należy sprawdzić w poszukiwaniu szablonów. Jeśli szablon nie istnieje w pierwszym folderze, sprawdza następny itd.

Przypuśćmy, że znaleziono szablon o nazwie news/article_detail.html. Oto jak mógłby on wyglądać:

{% extends "base.html" %}

{% block title %}Artykuły z roku {{ year }}{% endblock %}

{% block content %}
<h1>Artykuły 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ą podwójne nawiasy klamrowe. Element {{ article.headline }} oznacza “W tym miejscu wyświetl zawartość atrybutu headline artykułu”. Kropek nie używa się tylko i wyłącznie pobierania atrybutów: mogą również służyć do pobierania danych ze słownika, danych z indeksu lub wywoływania funkcji.

Zauważ, że {{ article.pub_date|date:"Y-m-d" }} wykorzystuje Uniksowy znak potoku (znak “|”). To tak zwany filtr szablonu, który umożliwia konwersję wartości 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).

Możliwe jest tworzenie łańcucha filtrów. Możesz napisać własne filtry. Możesz napisać własne znaczniki szablonów, które wykonują dowolny napisany przez Ciebie kod Pythona.

Django stosuje pojęcie “dziedziczenia szablonów”. To właśnie tym zajmuje się fragment {% extends "base.html" %}. Oznacza on: “Najpierw załaduj szablon o nazwie ‘base’, który ma zdefiniowaną określoną liczbę bloków, a następnie zastąp oryginalne bloki poniższym kodem”. W dużym skrócie możemy powiedzieć, że takie rozwiązanie drastycznie zmniejsza powtarzanie kodu w szablonach: każdy szablon definiuje tylko to, co jest w nim unikatowe.

Oto przykładowy wygląd 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 ogólny wygląd witryny (razem z logo), a także wskazuje “dziury” do wypełnienia przez szablony potomne. Takie rozwiązanie znacząco upraszcza zmianę wyglądu witryny, bo wielu sytuacjach wystarczy zmienić tylko jeden plik — szablon bazowy.

Umożliwia również tworzenie wielu wersji danej witryny z różnymi szablonami bazowymi przy stosowaniu tych samych szablonów potomnych. Twórcy Django wykorzystali tę technikę do stworzenia całkowicie innej edycji witryny przystosowanej do telefonów komórkowych — zrobili to, tworząc nowy szablon bazowy.

Pamiętaj, że nie musisz używać systemu szablonów Django, jeśli preferujesz inny. Choć system szablonów Django jest dobrze zintegrowany z warstwą modelu Django, nic nie zmusza Cię do jego stosowania. Równie dobrze nikt nie zmusza Cię do stosowania systemu ORM wbudowanego w Django. Możesz wykorzystać inny mechanizm warstwy abstrakcji bazodanowej, czytać dane z plików XML, czytać dane z plików tekstowych lub robić cokolwiek innego. Każdy element Django — modele, widoki i szablony — jest mocno odseparowany od pozostałych elementów.

To dopiero początek

Niniejszy tekst to bardzo skrótowy opis funkcjonalności dostępnej w Django. Oto niektóre z innych użytecznych funkcji:

  • System cache integrujący się z memcached i innymi mechanizmami (pliki, baza danych).
  • System rozpowszechniania (en), który umożliwia tworzenie plików dla czytników RSS i Atom poprzez pisanie niewielkich klas Pythonowych.
  • Bardziej seksowne funkcje automatycznie generowanego panelu administracyjnego — jest naprawdę rozbudowany.

Następnym oczywistym krokiem jest pobranie Django, przerobienie tutoriala i dołączenie do społeczności. Dziękujemy za zainteresowanie!

Pytania/Wsparcie

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