Widoki generyczne, czyli ogólne, w Django zostały napisane, by urzeczywistniać zasadę DRY, tj niepowtarzania tych samych czynności.
Budowa kontrolerów, zwanych w Django widokami, jest bowiem dla większości stron webowych podobna, a więc jest możliwe stworzenie abstrakcyjnego, ogólnego kodu, który będzie mógł być zastosowany zawsze wtedy, gdy spełnione są pewne założenia.
Okazuje się napisanie takiego kodu jest możliwe, został on napisany i jest możliwy do wykorzystania z Django.
Konkretnie Django dostarcza widoki "ogólne", które mogą wykonywać następujące zadania:
Jedną z ciekawszych właściwości widoków ogólnych Django jest to, że mogą one być używane na dwa sposoby.
Po pierwsze można dzięki nim zbudować aplikację nie pisząc w ogóle funkcji widoku. Informację o skorzystaniu z widoku generycznego umieszczamy w wtedy w urls.py. Oto przykład najprostszej sytuacji tego typu - napisaliśmy statyczną stronę i umieściliśmy jej kod html w pliku strona.html. Sytuacja taka jest całkiem realna - w każdej niemal aplikacji zdarzają się strony, które będą modyfikowane rzadko lub prawie wcale. Czasami w takich sytuacjach nie warto ich wpisaywać do bazy danych. Istnieje widok generyczny direct_to_template, który pozwala taką stronę wyświetlić. Załóżmy, że chcemy, żeby URL do naszej strony nazywał się http://jakas-domena.com/nasza-strona-statyczna/. Możemy więc w urls.py napisać:
from django.conf.urls.defaults import * from django.views.generic.simple import direct_to_template urlpatterns = patterns('', r('^nasza-strona-statyczna/$', direct_to_template, { 'template': 'strona.html' }) )
Jest to w zasadzie cała, kompletna, aplikacja Django - chyba najprostsza jaką możemy sobie wyobrazić.
Teraz drugi przykład. W tej samej dokładnie sytuacji chcemy jednak z jakichś powodów napisać własną funkcję widoku. Nie ma problemu, w pliku views.py wpisujemy:
from django.views.generic.simple import direct_to_template def static_page(request): return direct_to_template(request, template="strona.html")
Ten kod jest rzeczywiście prosty (i działa!), ale... wrażliwy na błędy i dlatego nieelegancki, poza tym nie daje nam zbyt wielu możliwości. Rozbudujmy go więc trochę.
from django.http import Http404 from django.template import TemplateDoesNotExist from django.views.generic.simple import direct_to_template def static_page(request, page): try: return direct_to_template(request, template="%s.html" % page) except TemplateDoesNotExist: raise Http404()
Po pierwsze zabezpieczamy się w ten sposób przez błędem nieistniejącego szablonu. Decydujemy, że ma się w takiej sytuacji wyświetlić strona błędu 404, co jest rozsądne, bo przecież na szablon jest po prostu statyczną stroną. Po drugie, nasza funkcja widoku przyjmuje drugi parametr - page. Zobaczmy jak urls.py może przekazać wartość tego parametru, i zależnie od tego zostanie wybrana jedna ze statycznych stron:
from django.conf.urls.defaults import * from django.views.generic.simple import direct_to_template from mysite.books.views import about_pages urlpatterns = patterns('', r('^nasza-strona-statyczna/(w+)/$', static_page), )
Znów mamy powyżej pełną aplikację Django. Fakt, że nadal banalną, bo do wyświetlania statycznych stron według URL nie potrzeba Django... ale chodzi o zasadę działania generycznych widoków, która w niebanalnych przypadkach pozostaje dokładnie taka sama.
Ciąg dalszy nastąpi ;)