Django w pigułce

Podane poniżej informacje mają na celu prezentację opisu technicznego pozwalającego zrozumieć w jaki sposób działa Django. W Django można napisać aplikację służącą do przechowywania informacji, która będzie pracować na bazie danych.

Teoretycznie można używać Djano bez bazy danych, gdyż oferujemy je wraz z systemem odwzorowania relacyjno-obiektowego. Ten system umożliwia definiowanie tabel.

Składanie danych modelu jest możliwe w oparciu o wiele metod przedstawiania modeli.

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

Wiersz poleceń w narzędziach administracyjnych umożliwia automatyczne tworzenie tabel baz danych.

manage.py syncdb

Dzięki użyciu tego polecenia zostają zostają ocenione dostępne modele i utworzone takie tabele bazy danych, których jeszcze nie było.

Fajną sprawą jest darmowy interfejs programistyczny dający dostęp do danych. Jest bezpłatny a przy tym naprawdę bogaty. Aby utworzyć API nie trzeba nawet generować 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()

Gdy modele zostaną już zdefiniowane Django będzie mogło w sposób automatyczny dokonać kreacji gotowego interfejsu administracyjnego to znaczy strony www pozwalającej użytkownikom uwierzytelnionym na usuwanie, dodawanie i edycję obiektów. Aktywacja takiego interfejsu następuje, jeśli doda się do kodu modelu następujący 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

Wszystko po to, aby nie tworzyć dużej ilości interfejsów administracyjnych wyłącznie do celów modyfikacji zawartości. Niekiedy już przy powstawaniu modeli system administracyjny jest od razu aktywny, a programista może poświęcić swój czas tej części interfejsu, która ma charakter publiczny.

Adresy URL bywają ładne i brzydkie. Django nakłania do stosowania tych bardziej eleganckich.

W celu przygotowania adresów URL dla aplikacji trzeba utworzyć moduł Pythona URLconf.

Jest to coś w rodzaju spisu zawartości aplikacji dzięki któremu adresy URL są znakomicie oddzielone od zasadniczej logiki aplikacji, a między wzorcami URL i funkcjami Pythona będzie zachodzić proste odwzorowanie.

Przykładowo:

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'),
)

Na czym konkretnie polega tego typu odwzorowanie? Odszukiwane jest pasujące wyrażenie regularne, a potem wywoływana jest odpowiadająca mu funkcja widoku. Wartości z adresów URL wychwytywane są poprzez wyrażenia regularne przy użyciu nawiasów. Najpierw dana osoba wysyła żądanie pobrania i w odpowiedzi na to Django poszukuje wśród wzorców taki, który odpowiadać będzie żądanemu adresowi URL, kończąc poszukiwania już przy pierwszym właściwym. Proces ten przebiega błyskawicznie. Odszukane wyrażenie regularne jest importowane i następuje wywołanie wskazanego widoku. Obiekt żądania z matadanymi trafia do każdego widoku, a ponadto trafiają tam zgromadzone podczas analizy wyrażenia regularnego wartości.

Widok może zwrócić obiekt posiadający zawartość żądanej witryny albo dokonać zgłoszenia wyjątku. Wszystko zależy od działań wykonanych przez użytkownika.

Co robi widok? Otóż pobiera on informacje według przekazanych parametrów, wczytuje szablon i renderuje ten szablon przy użyciu zgromadzonych danych. Pokażmy więc przykład widoku year_archive:

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

Django zawiera bogaty w funkcje system szablonów, cechuje go jednak prostota, więc nawet osoby wcześniej nie mające styczności z programowaniem mogą się nim posługiwać.

Aby do minimum ograniczyć redundację między szablonami Django posługuje się ścieżką wyszukiwania szablonów. Lista folderów wymagających weryfikacji – podczas poszukiwania szablonów – określona jest w pliku ustawień. Jeżeli szablon nie będzie się mieścił w pierwszym folderze, Django sprawdzać będzie kolejne aż do skutku.

Przyjrzyjmy się przykładowi szablonu news/article_detail.html.

{% 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 %}

{{ article.pub_date|date:”Y-m-d” }} używa znaku potoku (uniksowy znak „|”). Stanowi on filtr szablonu, umożliwiający konwersję wartości zmiennej. Na omawianym powyżej przykładzie filtr daty formatuje datę na wskazany tekst. Django daje dużo możliwości, w tym samodzielne tworzenie filtrów jak i łańcuchów filtrów czy też znaczników szablonów. Django zapewnia dziedziczenie szablonów (dzięki fragmentowi {% extends „base.html” %}.  Kolejność jest następująca: ładujemy szablon ze zdefiniowaną liczbą bloków, a potem oryginalne bloki zastępowane są poniższym kodem. Dzięki temu powtarzanie kodów w szablonach ulega ewidentnemu zmniejszeniu, a każdy szablon określa wyłącznie to co ma w sobie unikatowego.

Przydatny będzie jeszcze jeden przykład:

<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="sitelogo.gif" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>

Na pokazanym powyżej przykładzie szablon definiuje zasadniczy wygląd witryny łącznie z jej logo i określa luki jakie powinny zapełnić kolejne szablony. Gdybyśmy więc chcieli zmodyfikować wygląd strony, najczęściej w zupełności wystarczająca okaże się zmiana szablonu bazowego. Poza tym w Django możliwe jest przygotowanie wielu form strony na bazie rozmaitych szablonów bazowych przy użyciu tych samych szablonów potomnych. Jedno z fajnych osiągnięć twórców Django to możliwość dokonywania edycji witryny przystosowanej do telefonów komórkowych, co może mieć miejsce dzięki szablonowi bazowemu.

Korzystanie z systemu szablonów Django nie jest niczym koniecznym. Warto jednak mieć go na uwadze z tego względu, że jest on znakomicie zintegrowany z warstwą modelu Django. Używanie systemu ORM również nie stanowi konieczności, a to dlatego, że każdy z elementów Django jest znacznie odseparowany od pozostałych.