Niniejszy artykuł przedstawia ścieżkę tworzenia prostej aplikacji w Django 1.0. Jeżeli znasz poprzednie jego wersje ten artykuł pomoże ci w migracji do nowej wersji zawierającej kilka wstecznie niezgodnych zmian. Jeżeli nie znasz jeszcze frameworka - ten artykuł przedstawi ci jego budowę i możliwości.
Projekt, czyli katalog z wszystkimi plikami serwisu tworzymy wykonując polecenie
django-admin.py startproject NAZWA_PROJEKTU. Aplikacje, czyli poszczególne składowe projektu (wiadomości, komentarze, forum itd.) tworzymy wykonując w katalogu projektu polecenie
python manage.py startapp NAZWA_APLIKACJI. W artykule stworzymy projekt "blog" i aplikację "news":
django-admin.py startproject blog
cd blog
python manage.py startapp news
Kolejny etap to konfiguracja bazy danych i innych ustawień w pliku
settings.py. W tym artykule skorzystam z bazy SQLite konfigurując ją tak:
DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = 'baza' # Or path to database file if using sqlite3.
Dodatkowo zmieniam język na polski -
LANGUAGE_CODE = 'pl'. Inne ważne sekcje tego pliku, które będziemy modyfikować to:
- MEDIA_ROOT: ścieżka do katalogu z plikami statycznymi (grafika, css, js i inne). Zazwyczaj stosuje się katalog o nazwie "site_media" lub "media"
- TEMPLATE_DIRS: lista katalogów z szablonami aplikacji. W najprostszym przypadku można stworzyć katalog "templates" i dodać go do listy
- INSTALLED_APPS: lista zainstalowanych aplikacji. Stworzyliśmy aplikację "news" i żeby projekt ją "widział" musimy dodać ją do listy:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'news',
)
Teraz możemy stworzyć bazę danych i podstawowe tabele poleceniem:
python manage.py syncdb
W czasie wykonywania którego zostaniemy poproszeni o stworzenie konta superużytkownika podając login, email i hasło.
By uruchomić
serwer deweloperski służący do testowania projektu wystarczy wydać polecenie:
python manage.py runserver
Strona będzie dostępna pod adresem http://localhost:8000/
Django posiada rozbudowany i generowany "automatycznie" Panel Admina dla naszych aplikacji. By go uruchomić upewnij się czy masz
'django.contrib.admin', dodane do
INSTALLED_APPS (jeżeli nie to dodaj i wykonaj polecenie "syncdb"). Następnie edytuj plik
urls.py do postaci:
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/(.*)', admin.site.root),
)
Pod adresem
http://localhost:8000/admin/ dostępny będzie Panel Admina, do którego logujemy się danymi podanymi przy tworzeniu bazy danych / superużytkownika. Po zalogowaniu zobaczymy coś takiego:
Możemy zarządzać kontami użytkowników, czy też tworzyć grupy posiadające różne uprawnienia. "Strony" to aplikacja, która przydaje się gdy chcemy uruchomić więcej niż jeden serwis bazujący na tym samym kodzie i bazie danych (na razie omijamy tą aplikację). Stworzone przez nas aplikacje będą posiadały w Panelu Admina interfejs pozwalający na zarządzanie rekordami (dodaj, edytuj, usuń itp.).
Każda tabela tworzona przez Django opisana jest modelem - klasą zawierającą definicje poszczególnych kolumn. Modele znajdują się w plikach
models.py poszczególnych aplikacji. W naszym przypadku -
news/models.py. Oto gotowe modele dla kategorii wiadomości i samych wiadomości:
# -*- coding: utf-8 -*-
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255, verbose_name='Nazwa Kategorii')
slug = models.SlugField(max_length=255, unique=True, verbose_name='Odnośnik')
icon = models.ImageField(upload_to='icons', verbose_name='Ikonka Kategorii', blank=True)
class Meta:
verbose_name = "Kategoria"
verbose_name_plural = "Kategorie"
def __str__(self):
return self.name
def __unicode__(self):
return self.name
class News(models.Model):
category = models.ManyToManyField(Category, verbose_name='Kategorie')
title = models.CharField(max_length=255, verbose_name='Tytuł')
slug = models.SlugField(max_length=255, unique=True, verbose_name='Odnośnik')
text = models.TextField(verbose_name='Treść')
date = models.DateTimeField(verbose_name='Data dodania')
wykop = models.CharField(max_length=255, verbose_name='Wykop', blank=True)
class Meta:
verbose_name = "Wiadomość"
verbose_name_plural = "Wiadomości"
def __str__(self):
return self.title
def __unicode__(self):
return self.title
def get_absolute_url(self):
return '/news/' + self.slug + '/'
Mamy model "Category" dla listy kategorii - posiadających nazwę ("name"), odnośnik ("slug", nazwa pozbawiona znaków niedopuszczanych w URLach), oraz "pole" na ikonę kategorii - "icon". Jak widać każe z tych pól ma określony typ -
models.CharField - pole tekstowe (VARCHAR),
models.SlugField - pole tekstowe z walidacją znaków niedopuszczanych w odnośnikach, czy też np.
models.TextField - pole tekstowe (TEXT). Pole
ManyToManyField to pole relacji pozwalające przypisywać wiele kategorii do danej wiadomości.
Opis wszystkich pól i argumentów jakie przyjmują dostępny jest w oddzielnym artykule. Gdy mamy gotowy model możemy stworzyć tabele. Wystarczy ponownie wykonać:
python manage.py syncdb
Dla Django 1.0 konfiguracja Panelu Admina dla modeli odbywa się poprzez plik
admin.py umieszczony w katalogu aplikacji (news/admin.py). Oto najprostszy przypadek udostępniania modeli w PA:
# -*- coding: utf-8 -*-
from django.contrib import admin
#import pliku z modelami
from news.models import *
#rejestrujemy każdy model podając jego nazwę
admin.site.register(Category)
admin.site.register(News)
Po restarcie serwera deweloperskiego w Panelu Admina powinniśmy zobaczyć nasze modele:
Możemy teraz dowolnie zarządzać danymi w tych modelach.
Panel Admina posiada bardzo szerokie możliwości dopasowywania. Za pomocą klasy
NAZWA_MODELUAdmin możemy wpływać na wygląd formularzy dodawania/edycji, dane wyświetlane na liście istniejących wpisów i znacznie więcej. Oto przykład:
# -*- coding: utf-8 -*-
from django.contrib import admin
from news.models import *
# dla kategorii
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name','icon')
prepopulated_fields = {'slug': ('name',)}
# dla wiadomości
class NewsAdmin(admin.ModelAdmin):
list_display = ('title','date')
prepopulated_fields = {'slug': ('title',)}
# rejestracja wraz z podaniem klasy konfigurującej PA
admin.site.register(Category, CategoryAdmin)
admin.site.register(News, NewsAdmin)
Zastosowaliśmy tutaj
list_display - listę pól, jakie mają byś wyświetlane na liście wpisów, oraz
prepopulated_fields - słownik określający pola, z których mają być generowane wartości dla pól odnośnikowych "Slug". Dodając nazwę kategorii ("name") automatycznie wstawiony zostanie przefiltrowany tekst do pola odnośnika "slug". Podobnie dla wiadomości.
W tej chwili mamy gotowy Panel Admina zarządzający naszym "blogiem". Brakuje nam części wyświetlającej wiadomości dla odwiedzających stronę.
Django stosuje wzorzec projektowy Model-Szablon-Widok, gdzie logika bazodanowa jest w modelu, szablon określa wygląd (HTML), a widok spina to razem zwracając gotowy wynik (gotową stronę). Widoki definiowane są w pliku
views.py aplikacji (news/views.py). Oto prosty widok:
# -*- coding: utf-8 -*-
from django.template import RequestContext
from django.shortcuts import render_to_response
from news.models import *
def index(request):
return render_to_response('index.html',
{'zmienna': 'Jestem widokiem'},
context_instance=RequestContext(request))
Każdy widok to funkcja przyjmująca co najmniej jeden argument - "request" (dane żądania, POST, GET, SESSION itd.) i musi zwrócić odpowiedź - zazwyczaj będziemy stosować funkcję "
render_to_response" zwracającą gotowy wynik z wykorzystaniem szablonu. W tym przykładzie używamy szablonu
index.html (umieszczonego w katalogu templates) o kodzie:
<h1>Moja Strona </h1>
{{ zmienna }}
render_to_response przyjmuje kilka argumentów - nazwę szablonu, słownik ze zmiennymi przekazywanymi do szablonu, oraz "RequestContext", co obecnie możemy pominąć (udostępnianie zmiennych globalnych dla wszystkich szablonów).
Opis widoków oraz obiektu request znajdziemy w oddzielnym artykule.
W Django odnośniki, pod którymi są dostępne określone widoki są mapowane za pomocą reguł z wyrażeniami regularnymi w plikach
urls.py. W naszym pliku urls.py mamy już podaną regułę dla panelu admina, teraz musimy podać regułę dla naszego widoku index:
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/(.*)', admin.site.root),
(r'^/?$', 'news.views.index'),
)
Reguła mapująca ma postać:
(r'REGUŁA', 'WIDOK'),
Gdzie do widoku odwołujemy się poprzez
nazwa_aplikacji.views.nazwa_widoku.
Opis mapowania odnośników znajdziemy w oddzielnym artykule. Po zapisaniu zmian pod adresem http://localhost:8000/ powinniśmy zobaczyć nasz widok:
Mając modele możemy operować na nich (pobierać, dodawać, czy edytować dane) poprzez ORM Django. Standardowo dostęp do modelu uzyskujemy poprzez:
NAZWA_MODELU.objects.METODA_OPERACJI()
Przykładowo pobranie kategorii o ID 1 wyglądałoby tak:
Category.objects.get(id=1)
A wszystkich wiadomości tak:
News.objects.all()
Opis wszystkich możliwości ORMa znajduje się w oddzielnym artykule. Zmodyfikujmy teraz nasz widok do postaci:
def index(request):
news = News.objects.all().order_by('-id')
return render_to_response('index.html',
{'news': news},
context_instance=RequestContext(request))
Jak widać pobieramy wszystkie wiadomości, sortujemy je malejąco po ID i wynik przekazujemy do szablonu:
<h1>Moja Strona </h1>
{% for n in news %}
<h3>{{ n.title }}</h3>
{{ n.text|safe }}<br />
{{ n.date|date:"Y.m.d H:i" }}
{% endfor %}
W efekcie na stronie głównej pojawi się lista wiadomości. Jak widać szablony Django posiadają szereg filtrów i tagów, z których dość często będziemy korzystać. Pętla "for" pozwala wyświetlić po kolei dane z listy. Filtry stosowane na zmiennych
{{ zmienna|filtr|filtr2 }} mogą określać ich formatowanie (filtr |date określający wyświetlany format czasu), czy też np |safe zezwalać na stosowanie tagów HTML w przesłanej zmiennej. Szablony obsługują także dziedziczenie - możliwość definiowana bloków w szablonie głównym i dziedziczenia go przez inne szablony, które wypełniają danymi istniejące bloki i zwracające kompletną stronę.
Opis szablonów znajdziemy w oddzielnym artykule. O tym i innych możliwościach Django w następnej części (lub też możesz odkrywać je samemu czytając dokumentacje i istniejące artykuły i przykłady).
- Dodany: 08.09.2008 przez riklaunim