Darmowy fragment publikacji:
Tytuł oryginału: Web Development with Django Cookbook
Tłumaczenie: Łukasz Piwko
ISBN: 978-83-283-1107-7
Copyright © Packt Publishing 2014.
First published in the English language under the title ‘Web Development with Django Cookbook -
9781783286898’
Polish edition copyright © 2015 by Helion S.A.
All rights reserved.
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording or by any information storage retrieval system,
without permission from the Publisher.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną,
fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich
właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były
kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane
z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie
ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji
zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Pliki z przykładami omawianymi w książce można znaleźć pod adresem:
ftp://ftp.helion.pl/przyklady/apindj.zip
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/apindj
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Printed in Poland.
• Kup książkę
• Poleć książkę
• Oceń książkę
• Księgarnia internetowa
• Lubię to! » Nasza społeczność
Spis tre(cid:258)ci
O autorze
O recenzentach
Wst(cid:218)p
Rozdzia(cid:239) 1. Wprowadzenie do systemu Django 1.6
Wprowadzenie
Praca w (cid:258)rodowisku wirtualnym
Tworzenie struktury plików projektu
Zarz(cid:200)dzanie zale(cid:285)no(cid:258)ciami projektu za pomoc(cid:200) narz(cid:218)dzia pip
Do(cid:239)(cid:200)czanie zewn(cid:218)trznych zale(cid:285)no(cid:258)ci do projektu
Definiowanie (cid:258)cie(cid:285)ek wzgl(cid:218)dnych w ustawieniach
Dynamiczne ustawianie warto(cid:258)ci zmiennej STATIC_URL dla u(cid:285)ytkowników systemu Subversion
Dynamiczne ustawianie warto(cid:258)ci zmiennej STATIC_URL dla u(cid:285)ytkowników systemu Git
Tworzenie i do(cid:239)(cid:200)czanie ustawie(cid:241) lokalnych
Ustawianie domy(cid:258)lnego kodowania UTF-8 w konfiguracji MySQL
Ustawianie w(cid:239)asno(cid:258)ci ignore systemu Subversion
Tworzenie pliku z informacjami o ignorowanych zasobach w systemie Git
Usuwanie skompilowanych plików Pythona
Ustalanie kolejno(cid:258)ci importowania plików Pythona
Definiowanie mo(cid:285)liwych do zmienienia ustawie(cid:241) aplikacji
Rozdzia(cid:239) 2. Struktury bazy danych
Wprowadzenie
Stosowanie domieszek do modeli
Tworzenie domieszek do modeli przy u(cid:285)yciu metod zwi(cid:200)zanych z adresami URL
Tworzenie domieszek do modeli do tworzenia i modyfikowania dat
7
9
11
15
16
16
18
20
21
23
25
26
28
29
30
32
32
33
35
37
37
38
39
42
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
Tworzenie domieszek do modeli do obs(cid:239)ugi metaznaczników
Tworzenie domieszek do modeli do obs(cid:239)ugi relacji generycznych
Obs(cid:239)uga pól wieloj(cid:218)zycznych
Sposób u(cid:285)ycia migracji South
Zmienianie klucza obcego na pole wiele do wielu przy u(cid:285)yciu narz(cid:218)dzia South
Rozdzia(cid:239) 3. Formularze i widoki
Wprowadzenie
Przekazywanie obiektu HttpRequest do formularza
Sposób u(cid:285)ycia metody save formularza
Wysy(cid:239)anie obrazów na serwer
Tworzenie uk(cid:239)adu formularza przy u(cid:285)yciu aplikacji django-crispy-forms
Filtrowanie list obiektów
Zarz(cid:200)dzanie listami stronicowanymi
Komponowanie widoków na bazie klas
Rozdzia(cid:239) 4. Szablony i JavaScript
Wprowadzenie
Konfiguracja pliku szablonowego base.html
Do(cid:239)(cid:200)czanie ustawie(cid:241) JavaScript
Wykorzystywanie atrybutów danych HTML5
Otwieranie szczegó(cid:239)ów obiektu w wyskakuj(cid:200)cym okienku
Implementacja ci(cid:200)g(cid:239)ego przewijania
Implementacja wid(cid:285)etu polubie(cid:241)
Wysy(cid:239)anie obrazów przy u(cid:285)yciu technologii Ajax
Rozdzia(cid:239) 5. Tworzenie w(cid:239)asnych filtrów i znaczników szablonowych
Wprowadzenie
Stosowanie konwencjonalnych rozwi(cid:200)za(cid:241) przy tworzeniu filtrów i znaczników szablonowych
Tworzenie filtru szablonowego do pokazywania, ile dni up(cid:239)yn(cid:218)(cid:239)o
Tworzenie filtru szablonowego do pobierania pierwszego obiektu mediów
Tworzenie filtru szablonowego dostosowuj(cid:200)cego adresy URL do potrzeb u(cid:285)ytkownika
Tworzenie znacznika szablonowego do do(cid:239)(cid:200)czania szablonu, je(cid:258)li istnieje
Tworzenie znacznika szablonowego do (cid:239)adowania zestawu obiektów do szablonu
Tworzenie znacznika szablonowego do przetwarzania tre(cid:258)ci jako szablonu
Tworzenie znacznika szablonowego do modyfikowania parametrów zapyta(cid:241)
Rozdzia(cid:239) 6. Modelowanie panelu administracyjnego
Wprowadzenie
Dostosowywanie kolumn na stronie listy zmian
Tworzenie czynno(cid:258)ci administracyjnych
Tworzenie filtrów listy zmian
Zamienianie ustawie(cid:241) administracyjnych na zewn(cid:218)trzne aplikacje
Wstawianie map do formularza zmian
43
46
50
55
58
61
61
61
64
66
70
74
80
83
87
87
88
90
93
97
100
102
108
117
117
118
119
121
123
124
127
131
133
137
137
138
141
144
147
149
4
Poleć książkęKup książkęSpis tre(cid:286)ci
Rozdzia(cid:239) 7. Django CMS
Wprowadzenie
Tworzenie szablonów dla systemu Django CMS
Konfigurowanie menu stron
Konwertowanie aplikacji na aplikacj(cid:218) CMS
Dodawanie w(cid:239)asnej nawigacji
Pisanie w(cid:239)asnej wtyczki
Dodawanie nowych pól do strony CMS-a
Rozdzia(cid:239) 8. Struktury hierarchiczne
Wprowadzenie
Tworzenie kategorii hierarchicznych
Tworzenie interfejsu do administracji kategoriami przy u(cid:285)yciu aplikacji django-mptt-admin
Tworzenie interfejsu do administracji kategoriami przy u(cid:285)yciu aplikacji django-mptt-tree-editor
Generowanie kategorii w szablonie
Wybieranie kategorii w formularzach przy u(cid:285)yciu pola pojedynczego wyboru
Wybieranie wielu kategorii w formularzach przy u(cid:285)yciu listy pól wyboru
Rozdzia(cid:239) 9. Importowanie i eksportowanie danych
Wprowadzenie
Importowanie danych z lokalnego pliku CSV
Importowanie danych z lokalnego pliku Excela
Importowanie danych z zewn(cid:218)trznego pliku w formacie JSON
Importowanie danych z zewn(cid:218)trznego pliku XML
Tworzenie kana(cid:239)ów RSS z mo(cid:285)liwo(cid:258)ci(cid:200) filtrowania
Dostarczanie danych do u(cid:285)ytkowników zewn(cid:218)trznych za pomoc(cid:200) us(cid:239)ugi Tastypie
Rozdzia(cid:239) 10. Sztuczki i bajery
Wprowadzenie
Pos(cid:239)ugiwanie si(cid:218) pow(cid:239)ok(cid:200) Django
Tworzenie przyjaznych adresów
Zast(cid:218)powanie modelu administracji
W(cid:239)(cid:200)czanie i wy(cid:239)(cid:200)czanie paska narz(cid:218)dzi debugowania
Sposób u(cid:285)ycia programu po(cid:258)rednicz(cid:200)cego ThreadLocalMiddleware
Buforowanie warto(cid:258)ci metody
Wysy(cid:239)anie raportów o b(cid:239)(cid:218)dach na adres e-mail
Wdra(cid:285)anie aplikacji na serwerze Apache przy u(cid:285)yciu modu(cid:239)u mod_wsgi
Tworzenie i u(cid:285)ywanie skryptu wdra(cid:285)ania Fabric
Skorowidz
157
157
158
161
164
166
168
173
179
179
181
184
186
188
190
191
197
197
197
199
201
206
209
214
217
217
218
220
222
226
229
231
232
234
241
251
5
Poleć książkęKup książkęPoleć książkęKup książkę5
Tworzenie w(cid:239)asnych
filtrów i znaczników
szablonowych
W rozdziale:
(cid:81) Stosowanie konwencjonalnych rozwi(cid:200)za(cid:241) przy tworzeniu filtrów
i znaczników szablonowych
(cid:81) Tworzenie filtru szablonowego do pokazywania, ile dni up(cid:239)yn(cid:218)(cid:239)o
(cid:81) Tworzenie filtru szablonowego do pobierania pierwszego obiektu mediów
(cid:81) Tworzenie filtru szablonowego dostosowuj(cid:200)cego adresy URL do potrzeb
u(cid:285)ytkownika
(cid:81) Tworzenie znacznika szablonowego do do(cid:239)(cid:200)czania szablonu, je(cid:258)li istnieje
(cid:81) Tworzenie znacznika szablonowego do (cid:239)adowania zestawu obiektów do szablonu
(cid:81) Tworzenie znacznika szablonowego do przetwarzania tre(cid:258)ci jako szablonu
(cid:81) Tworzenie znacznika szablonowego do modyfikowania parametrów zapyta(cid:241)
Wprowadzenie
Jak wiadomo, Django zawiera do(cid:258)(cid:202) rozbudowany system szablonowy obs(cid:239)uguj(cid:200)cy mi(cid:218)dzy in-
nymi dziedziczenie szablonów, filtry do zmieniania reprezentacji warto(cid:258)ci oraz znaczniki ob-
s(cid:239)uguj(cid:200)ce logik(cid:218) prezentacyjn(cid:200). Ponadto Django umo(cid:285)liwia dodawanie filtrów i znaczników sza-
blonowych we w(cid:239)asnych aplikacjach. Niestandardowe filtry i znaczniki powinny znajdowa(cid:202) si(cid:218)
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
w pliku biblioteki znaczników szablonowych w pakiecie Pythona templatetags w aplikacji.
Bibliotek(cid:218) tak(cid:200) mo(cid:285)na za(cid:239)adowa(cid:202) w wybranym szablonie za pomoc(cid:200) znacznika szablonowego
{ load }. W tym rozdziale utworzymy kilka przydatnych filtrów i znaczników daj(cid:200)cych edyto-
rom szablonów dodatkowe mo(cid:285)liwo(cid:258)ci dzia(cid:239)ania.
Stosowanie konwencjonalnych rozwi(cid:200)za(cid:241)
przy tworzeniu filtrów
i znaczników szablonowych
Je(cid:258)li programista nie zastosuje spójnych regu(cid:239) dzia(cid:239)ania, w jego niestandardowych filtrach
i znacznikach szablonowych szybko mo(cid:285)e powsta(cid:202) straszny ba(cid:239)agan. Sk(cid:239)adniki te powinny by(cid:202)
jak najbardziej pomocne dla edytorów szablonów. Powinny by(cid:202) zarówno wygodne w u(cid:285)yciu,
jak i elastyczne. W tej recepturze przedstawiam pewne konwencje, które mo(cid:285)na stosowa(cid:202) przy
rozszerzaniu systemu szablonowego Django.
Jak to zrobi(cid:202)
Rozszerzaj(cid:200)c system szablonów Django, stosuj si(cid:218) do nast(cid:218)puj(cid:200)cych zalece(cid:241):
1. Nie twórz i nie u(cid:285)ywaj niestandardowych filtrów ani znaczników szablonowych,
je(cid:258)li logika strony lepiej pasuje do widoku, procesora kontekstu lub metod modelu.
Je(cid:285)eli strona jest specyficzna dla kontekstu, na przyk(cid:239)ad zawiera list(cid:218) obiektów
albo widok szczegó(cid:239)ów obiektów, za(cid:239)aduj obiekty w widoku. Je(cid:258)li chcesz wy(cid:258)wietli(cid:202)
pewn(cid:200) tre(cid:258)(cid:202) na ka(cid:285)dej stronie, utwórz procesor kontekstu. Je(cid:285)eli trzeba pobra(cid:202) niektóre
w(cid:239)asno(cid:258)ci obiektu niezwi(cid:200)zane z kontekstem szablonu, lepiej jest wykorzysta(cid:202)
niestandardowe metody modelu zamiast filtrów szablonowych.
2. Do nazwy biblioteki znaczników szablonowych dodawaj przyrostek _tags.
Dzi(cid:218)ki nadaniu bibliotece innej nazwy ni(cid:285) aplikacji unikniesz problemów
z niejednoznaczno(cid:258)ci(cid:200) przy importowaniu.
3. W nowo utworzonej bibliotece oddziel filtry od znaczników, na przyk(cid:239)ad za pomoc(cid:200)
komentarzy, jak poni(cid:285)ej:
# -*- coding: UTF-8 -*-
from django import template
register = template.Library()
### FILTRY ###
# ...kod (cid:296)ród(cid:225)owy filtrów...
### ZNACZNIKI ###
# ...kod (cid:296)ród(cid:225)owy znaczników...
118
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
4. Twórz takie znaczniki szablonowe, które jest (cid:239)atwo zapami(cid:218)ta(cid:202); stosuj do tego
poni(cid:285)sze konstrukcje:
(cid:81) for [nazwa_aplikacji.nazwa_modelu]— konstrukcja umo(cid:285)liwiaj(cid:200)ca
wykorzystanie okre(cid:258)lonego modelu.
(cid:81) using [nazwa_szablonu]— konstrukcja umo(cid:285)liwiaj(cid:200)ca wykorzystanie szablonu
dla wyniku znacznika szablonowego.
(cid:81) limit [liczba]— konstrukcja umo(cid:285)liwiaj(cid:200)ca ograniczenie wyników
do okre(cid:258)lonej liczby.
(cid:81) as [zmienna_kontekstowa]— konstrukcja umo(cid:285)liwiaj(cid:200)ca zapisanie wyników
w zmiennej kontekstowej, której pó(cid:283)niej mo(cid:285)na u(cid:285)ywa(cid:202) wielokrotnie.
5. Staraj si(cid:218) nie u(cid:285)ywa(cid:202) w znacznikach szablonowych zbyt wielu warto(cid:258)ci
zdefiniowanych pozycyjnie, chyba (cid:285)e ich przeznaczenie jest oczywiste.
W przeciwnym razie programi(cid:258)ci szablonów mog(cid:200) mie(cid:202) z nimi problemy.
6. Twórz jak najwi(cid:218)cej rozwi(cid:200)zywalnych argumentów. (cid:146)a(cid:241)cuchy bez cudzys(cid:239)owów
powinno si(cid:218) traktowa(cid:202) jak zmienne kontekstowe, które trzeba rozwi(cid:200)za(cid:202), lub jako
krótkie s(cid:239)owa przypominaj(cid:200)ce o strukturze sk(cid:239)adników znacznika szablonowego.
Zobacz równie(cid:285)
(cid:81) Receptura „Tworzenie filtru szablonowego do pokazywania, ile dni up(cid:239)yn(cid:218)(cid:239)o”
(cid:81) Receptura „Tworzenie filtru szablonowego do pobierania pierwszego obiektu mediów”
(cid:81) Receptura „Tworzenie filtru szablonowego dostosowuj(cid:200)cego adresy URL do potrzeb
u(cid:285)ytkownika”
(cid:81) Receptura „Tworzenie znacznika szablonowego do do(cid:239)(cid:200)czania szablonu, je(cid:258)li istnieje”
(cid:81) Receptura „Tworzenie znacznika szablonowego do (cid:239)adowania zestawu obiektów
do szablonu”
(cid:81) Receptura „Tworzenie znacznika szablonowego do przetwarzania tre(cid:258)ci jako szablonu”
(cid:81) Receptura „Tworzenie znacznika szablonowego do modyfikowania parametrów zapyta(cid:241)”
Tworzenie filtru szablonowego
do pokazywania, ile dni up(cid:239)yn(cid:218)(cid:239)o
Nie ka(cid:285)dy rejestruje daty, a je(cid:258)li chodzi o tworzenie i modyfikowanie naj(cid:258)wie(cid:285)szych informacji,
to w wielu przypadkach wygodniejsze jest rejestrowanie ró(cid:285)nic w czasie, na przyk(cid:239)ad wpis na
blogu zosta(cid:239) opublikowany trzy dni temu albo artyku(cid:239) opublikowano dzi(cid:258) i u(cid:285)ytkownik logowa(cid:239)
si(cid:218) po raz ostatni wczoraj. W tej recepturze pokazuj(cid:218), jak utworzy(cid:202) filtr szablonowy o nazwie
days_since, konwertuj(cid:200)cy daty na czytelne ró(cid:285)nice czasu.
119
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
Przygotowanie
Je(cid:258)li jeszcze tego nie zrobi(cid:239)e(cid:258), utwórz aplikacj(cid:218) utils i dodaj j(cid:200) do sekcji INSTALLED_APPS.
Nast(cid:218)pnie w tej aplikacji utwórz pakiet Pythona o nazwie templatetags (pakiety Pythona to
katalogi zawieraj(cid:200)ce pusty plik __init__.py).
Jak to zrobi(cid:202)
Utwórz plik o nazwie utility_tags.py z nast(cid:218)puj(cid:200)c(cid:200) zawarto(cid:258)ci(cid:200):
#utils/templatetags/utility_tags.py
# -*- coding: UTF-8 -*-
from datetime import datetime
from django import template
from django.utils.translation import ugettext_lazy as _
from django.utils.timezone import now as tz_now
register = template.Library()
### FILTRY ###
@register.filter
def days_since(value):
Zwraca liczb(cid:266) dni mi(cid:266)dzy aktualn(cid:261) dat(cid:261) a podan(cid:261) warto(cid:286)ci(cid:261).
today = tz_now().date()
if isinstance(value, datetime.datetime):
value = value.date()
diff = today - value
if diff.days 1:
return _( s dni temu ) diff.days
elif diff.days == 1:
return _( wczoraj )
elif diff.days == 0:
return _(u dzi(cid:258) )
else:
# Podano przysz(cid:225)(cid:261) dat(cid:266), zwraca sformatowan(cid:261) dat(cid:266).
return value.strftime( B d, Y )
Jak to dzia(cid:239)a
Je(cid:258)li zastosuje si(cid:218) ten filtr w takim szablonie jak poni(cid:285)szy, to wyrenderuje on napis typu wczoraj
albo 5 dni temu:
{ load utility_tags }
{{ object.created|days_since }}
Filtr ten mo(cid:285)na stosowa(cid:202) do warto(cid:258)ci typów date i datetime.
120
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
Ka(cid:285)da biblioteka znaczników szablonowych ma rejestr, w którym zebrane s(cid:200) filtry i znaczniki.
Filtry Django s(cid:200) funkcjami zarejestrowanymi przez dekorator register.filter. Domy(cid:258)lnie
filtrowi w systemie szablonów nadawana jest taka sama nazwa jak nazwa funkcji lub innego
wywo(cid:239)ywalnego obiektu. Jednak w razie potrzeby mo(cid:285)na ustawi(cid:202) inn(cid:200) nazw(cid:218), przekazuj(cid:200)c
opcj(cid:218) name do dekoratora:
@register.filter(name= humanized_days_since )
def days_since(value):
...
Sposób dzia(cid:239)ania filtra nie wymaga obszernych obja(cid:258)nie(cid:241). Najpierw odczytuje aktualn(cid:200) dat(cid:218).
Je(cid:258)li podana warto(cid:258)(cid:202) jest typu datetime, to zostaje pobrana data. Nast(cid:218)pnie obliczana jest ró(cid:285)-
nica mi(cid:218)dzy bie(cid:285)(cid:200)c(cid:200) a pobran(cid:200) dat(cid:200). Zwrot warto(cid:258)ci zale(cid:285)y od liczby dni ró(cid:285)nicy.
To nie wszystko
Ten filtr mo(cid:285)na (cid:239)atwo rozszerzy(cid:202) tak, aby pokazywa(cid:239) te(cid:285) ró(cid:285)nic(cid:218) w minutach i godzinach, na
przyk(cid:239)ad: w(cid:239)a(cid:258)nie teraz, 7 minut temu, 3 godziny temu itd. Trzeba tylko pos(cid:239)ugiwa(cid:202) si(cid:218) war-
to(cid:258)ciami typu datetime zamiast date.
Zobacz równie(cid:285)
(cid:81) Receptura „Tworzenie filtru szablonowego do pobierania pierwszego obiektu mediów”
(cid:81) Receptura „Tworzenie filtru szablonowego dostosowuj(cid:200)cego adresy URL
do potrzeb u(cid:285)ytkownika”
Tworzenie filtru szablonowego do
pobierania pierwszego obiektu mediów
Wyobra(cid:283) sobie, (cid:285)e tworzysz stron(cid:218) przegl(cid:200)du zawarto(cid:258)ci bloga i dla ka(cid:285)dego wpisu chcesz
pokaza(cid:202), jakie obrazy, klipy muzyczne lub filmy wideo znajduj(cid:200) si(cid:218) w jego tre(cid:258)ci. Aby to zro-
bi(cid:202), musisz pobra(cid:202) elementy img , object i embed z kodu HTML. W tej recepturze poka-
zuj(cid:218), jak to zrobi(cid:202) przy u(cid:285)yciu wyra(cid:285)e(cid:241) regularnych w filtrze get_first_media.
Przygotowanie
Najpierw utwórz aplikacj(cid:218) utils, któr(cid:200) trzeba doda(cid:202) do sekcji INSTALLED_APPS w ustawieniach,
a w aplikacji tej utwórz pakiet templatetags.
121
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
Jak to zrobi(cid:202)
Dodaj do pliku utility_tags.py poni(cid:285)szy kod:
#utils/templatetags/utility_tags.py
# -*- coding: UTF-8 -*-
import re
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
### FILTRY ###
media_file_regex = re.compile(r object .+? /object | (img|embed) [^ ]+ )
@register.filter
def get_first_media(content):
Zwraca pierwszy obraz lub plik Flash z tre(cid:286)ci HTML.
m = media_file_regex.search(content)
media_tag =
if m:
media_tag = m.group()
return mark_safe(media_tag)
Jak to dzia(cid:239)a
Je(cid:258)li znajduj(cid:200)ca si(cid:218) w bazie danych tre(cid:258)(cid:202) HTML jest poprawna, to poni(cid:285)szy kod umieszczony
w szablonie spowoduje pobranie elementów object , img i embed z tre(cid:258)ci pola obiektu
lub pobranie pustego (cid:239)a(cid:241)cucha, je(cid:258)li nie zostan(cid:200) znalezione (cid:285)adne media:
{ load utility_tags }
{{ object.content|get_first_media }}
Najpierw definiujemy skompilowane wyra(cid:285)enie regularne jako media_file_regex, nast(cid:218)pnie
w filtrze szukamy fragmentów tekstu pasuj(cid:200)cych do tego wzorca. Domy(cid:258)lnie w wyniku znaki
, i s(cid:200) zast(cid:218)powane encjami lt;, gt; oraz amp;. Jednak zastosowali(cid:258)my funkcj(cid:218)
mark_safe oznaczaj(cid:200)c(cid:200) wynik jako bezpieczny kod HTML, który mo(cid:285)na wstawi(cid:202) do szablonu
bez stosowania symboli zast(cid:218)pczych.
To nie wszystko
Ten filtr mo(cid:285)na (cid:239)atwo rozszerzy(cid:202) tak, aby rozpoznawa(cid:239) te(cid:285) elementy iframe (które od pew-
nego czasu s(cid:200) wykorzystywane przez serwisy Vimeo i YouTube) oraz nowe elementy HTML5
audio i video . Wystarczy tylko zmieni(cid:202) wyra(cid:285)enie regularne w nast(cid:218)puj(cid:200)cy sposób:
media_file_regex = re.compile(r iframe .+? /iframe |
r audio .+? /audio | video .+? /video |
r object .+? /object | (img|embed) [^ ]+ )
122
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
Zobacz równie(cid:285)
(cid:81) Receptura „Tworzenie filtru szablonowego do pokazywania, ile dni up(cid:239)yn(cid:218)(cid:239)o”
(cid:81) Receptura „Tworzenie filtru szablonowego dostosowuj(cid:200)cego adresy URL
do potrzeb u(cid:285)ytkownika”
Tworzenie filtru szablonowego
dostosowuj(cid:200)cego adresy URL
do potrzeb u(cid:285)ytkownika
Typowy u(cid:285)ytkownik internetu w przegl(cid:200)darce wpisuje adresy URL bez przedrostka okre(cid:258)laj(cid:200)-
cego protokó(cid:239) i bez ko(cid:241)cowego uko(cid:258)nika. W tej recepturze utworzymy filtr humanize_url pre-
zentuj(cid:200)cy adresy w skróconym formacie, tzn. skracaj(cid:200)cy d(cid:239)ugie adresy podobnie, jak robi to
portal Twitter z d(cid:239)ugimi odno(cid:258)nikami we wpisach.
Przygotowanie
Podobnie jak w poprzedniej recepturze musisz mie(cid:202) aplikacj(cid:218) utils dodan(cid:200) do sekcji INSTALLED_
(cid:180)APPS w ustawieniach, a w niej pakiet templatetags.
Jak to zrobi(cid:202)
W sekcji FILTRY biblioteki szablonowej utility_tags.py w aplikacji utils dodamy filtr o nazwie
humanize_url, który od razu zarejestrujemy:
#utils/templatetags/utility_tags.py
# -*- coding: UTF-8 -*-
import re
from django import template
register = template.Library()
### FILTRY ###
@register.filter
def humanize_url(url, letter_count):
Zwraca skrócony czytelny adres URL.
letter_count = int(letter_count)
re_start = re.compile(r ^https?:// )
re_end = re.compile(r /$ )
url = re_end.sub( , re_start.sub( , url))
if len(url) letter_count:
url = u s…¦ url[:letter_count - 1]
return url
123
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
Jak to dzia(cid:239)a
Filtru humanize_url mo(cid:285)na u(cid:285)ywa(cid:202) we wszystkich szablonach w nast(cid:218)puj(cid:200)cy sposób:
{ load utility_tags }
a href= {{ object.website }} target= _blank
{{ object.website|humanize_url:30 }}
/a
Filtr ten za pomoc(cid:200) wyra(cid:285)enia regularnego usuwa nazw(cid:218) protoko(cid:239)u z pocz(cid:200)tku i uko(cid:258)nik
z ko(cid:241)ca, a nast(cid:218)pnie skraca adres URL do okre(cid:258)lonej liczby znaków, dodaj(cid:200)c na ko(cid:241)cu wielo-
kropek, je(cid:258)li adres jest d(cid:239)u(cid:285)szy.
Zobacz równie(cid:285)
(cid:81) Receptura „Tworzenie filtru szablonowego do pokazywania, ile dni up(cid:239)yn(cid:218)(cid:239)o”
(cid:81) Receptura „Tworzenie filtru szablonowego do pobierania pierwszego obiektu mediów”
(cid:81) Receptura „Tworzenie znacznika szablonowego do do(cid:239)(cid:200)czania szablonu, je(cid:258)li istnieje”
Tworzenie znacznika szablonowego
do do(cid:239)(cid:200)czania szablonu, je(cid:258)li istnieje
W systemie Django dost(cid:218)pny jest znacznik szablonowy { include } renderuj(cid:200)cy i do(cid:239)(cid:200)czaj(cid:200)cy
szablon. Jednak czasami, je(cid:258)li szablon, który ma zosta(cid:202) do(cid:239)(cid:200)czony, nie istnieje, zostaje zg(cid:239)oszo-
ny b(cid:239)(cid:200)d. W tej recepturze pokazuj(cid:218), jak utworzy(cid:202) znacznik szablonowy { try_to_include },
do(cid:239)(cid:200)czaj(cid:200)cy do szablonu inny szablon, ale nie zg(cid:239)aszaj(cid:200)cy (cid:285)adnych b(cid:239)(cid:218)dów, je(cid:258)li nie znajdzie
sk(cid:239)adnika do do(cid:239)(cid:200)czenia.
Przygotowanie
Prac(cid:218) rozpoczniemy po raz kolejny od aplikacji utils, która powinna by(cid:202) ju(cid:285) zainstalowana
i gotowa do dodawania niestandardowych znaczników szablonowych.
Jak to zrobi(cid:202)
Znaczniki szablonowe sk(cid:239)adaj(cid:200) si(cid:218) z dwóch cz(cid:218)(cid:258)ci: funkcji przetwarzaj(cid:200)cej argumenty oraz
klasy w(cid:218)z(cid:239)owej zawieraj(cid:200)cej logik(cid:218) dzia(cid:239)ania znacznika i zwracania przez niego tre(cid:258)ci. Wyko-
naj nast(cid:218)puj(cid:200)ce czynno(cid:258)ci:
124
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
1. Najpierw napiszemy funkcj(cid:218) przetwarzaj(cid:200)c(cid:200) argumenty znacznika szablonowego:
#utils/templatetags/utility_tags.py
# -*- coding: UTF-8 -*-
from django import template
from django.template.loader import get_template
register = template.Library()
### ZNACZNIKI ###
@register.tag
def try_to_include(parser, token):
Sposób u(cid:298)ycia: { try_to_include szablon.html }
Je(cid:286)li szablon nie istnieje, nast(cid:261)pi cicha awaria. Je(cid:286)li szablon istnieje,
zostanie wygenerowany przy u(cid:298)yciu bie(cid:298)(cid:261)cego kontekstu.
try:
tag_name, template_name = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, \
Znacznik r wymaga pojedynczego argumentu. token.contents.split()[0]
return IncludeNode(template_name)
(cid:21). W nast(cid:218)pnej kolejno(cid:258)ci potrzebujemy klasy w(cid:218)z(cid:239)owej, która powinna znale(cid:283)(cid:202) si(cid:218)
w tym samym pliku:
class IncludeNode(template.Node):
def __init__(self, template_name):
self.template_name = template_name
def render(self, context):
try:
# (cid:224)adowanie i renderowanie szablonu.
template_name = template.resolve_variable(self.template_name, context)
included_template = get_template(template_name).render(context)
except template.TemplateDoesNotExist:
included_template =
return included_template
Jak to dzia(cid:239)a
Znacznik szablonowy { try_to_include } pobiera jeden argument okre(cid:258)laj(cid:200)cy nazw(cid:218) sza-
blonu — template_name. Zatem w funkcji try_to_include próbujemy przypisa(cid:202) podzielon(cid:200) tre(cid:258)(cid:202)
argumentu token tylko do zmiennych tag_name (któr(cid:200) jest try_to_include) i template_name.
Je(cid:258)li to si(cid:218) nie uda, zostaje zg(cid:239)oszony b(cid:239)(cid:200)d sk(cid:239)adni szablonu. Funkcja zwraca obiekt IncludeNode,
któremu nadaje pole template_name do u(cid:285)ytku w pó(cid:283)niejszym czasie.
W metodzie render obiektu IncludeNode rozwi(cid:200)zujemy zmienn(cid:200) template_name. Je(cid:285)eli do
znacznika szablonowego zosta(cid:239)a przekazana zmienna kontekstowa, to zostanie ona u(cid:285)yta jako
warto(cid:258)(cid:202) zmiennej template_name. Je(cid:258)li do znacznika szablonowego zosta(cid:239) przekazany (cid:239)a(cid:241)cuch
125
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
w cudzys(cid:239)owie, to jako warto(cid:258)(cid:202) zmiennej template_name zostanie wykorzystany tekst z tego
cudzys(cid:239)owu.
Na koniec próbujemy za(cid:239)adowa(cid:202) i wyrenderowa(cid:202) szablon przy u(cid:285)yciu bie(cid:285)(cid:200)cego kontekstu
szablonowego. Je(cid:258)li si(cid:218) to nie uda, zwracamy pusty (cid:239)a(cid:241)cuch.
Znacznik ten mo(cid:285)e by(cid:202) przydatny w przynajmniej dwóch sytuacjach:
(cid:81) przy do(cid:239)(cid:200)czaniu szablonu, którego (cid:258)cie(cid:285)ka jest zdefiniowana w modelu, na przyk(cid:239)ad:
{ load utility_tags }
{ try_to_include object.template_path }
(cid:81) przy do(cid:239)(cid:200)czaniu szablonu, którego (cid:258)cie(cid:285)ka jest zdefiniowana przy u(cid:285)yciu znacznika
szablonowego { with } gdzie(cid:258) wysoko w zakresie zmiennej kontekstowej szablonu.
Jest to szczególnie przydatne, gdy trzeba utworzy(cid:202) w(cid:239)asne uk(cid:239)ady dla wtyczek
w tek(cid:258)cie zast(cid:218)pczym szablonu w Django CMS:
#templates/cms/start_page.html
{ with editorial_content_template_path=
cms/plugins/editorial_content/start_page.html }
{ placeholder main_content }
{ endwith }
#templates/cms/plugins/editorial_content.html
{ load utility_tags }
{ if editorial_content_template_path }
{ try_to_include editorial_content_template_path }
{ else }
div
!-- Domy(cid:286)lna prezentacja wtyczki
dotycz(cid:261)cej tre(cid:286)ci redakcyjnej. --
/div
{ endif }
To nie wszystko
Za pomoc(cid:200) znaczników szablonowych { try_to_include } i { include } mo(cid:285)na do(cid:239)(cid:200)cza(cid:202)
szablony rozszerzaj(cid:200)ce inne szablony. Jest to szczególnie przydatne w du(cid:285)ych portalach za-
wieraj(cid:200)cych ró(cid:285)nego rodzaju listy, w których skomplikowane elementy, takie jak wid(cid:285)ety, maj(cid:200)
tak(cid:200) sam(cid:200) struktur(cid:218), ale korzystaj(cid:200) z ró(cid:285)nych (cid:283)róde(cid:239) danych.
Na przyk(cid:239)ad w szablonie listy artystów mo(cid:285)na do(cid:239)(cid:200)czy(cid:202) szablon elementu reprezentuj(cid:200)cego
jednego artyst(cid:218) w nast(cid:218)puj(cid:200)cy sposób:
{ load utility_tags }
{ for object in object_list }
{ try_to_include artists/includes/artist_item.html }
{ endfor }
126
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
Szablon ten rozszerza(cid:239)by szablon bazowy elementów w nast(cid:218)puj(cid:200)cy sposób:
{# templates/artists/includes/artist_item.html #}
{ extends utils/includes/item_base.html }
{ block item_title }
{{ object.first_name }} {{ object.last_name }}
{ endblock }
W szablonie bazowym znajdowa(cid:239)yby si(cid:218) definicje kodu HTML reprezentuj(cid:200)cego elementy
i do(cid:239)(cid:200)czany by(cid:239)by wid(cid:285)et Like:
{# templates/utils/includes/item_base.html #}
{ load likes_tags }
h3 { block item_title }{ endblock } /h3
{ if request.user.is_authenticated }
{ like_widget for object }
{ endif }
Zobacz równie(cid:285)
(cid:81) Receptura „Tworzenie szablonów dla systemu Django CMS” z rozdzia(cid:239)u 7.
„Django CMS”
(cid:81) Receptura „Pisanie w(cid:239)asnej wtyczki” z rozdzia(cid:239)u 7. „Django CMS”
(cid:81) Receptura „Implementacja wid(cid:285)etu polubie(cid:241)” z rozdzia(cid:239)u 4. „Szablony i JavaScript”
(cid:81) Receptura „Tworzenie znacznika szablonowego do do(cid:239)(cid:200)czania szablonu, je(cid:258)li istnieje”
(cid:81) Receptura „Tworzenie znacznika szablonowego do (cid:239)adowania zestawu obiektów
do szablonu”
(cid:81) Receptura „Tworzenie znacznika szablonowego do modyfikowania parametrów
zapyta(cid:241)”
Tworzenie znacznika szablonowego
do (cid:239)adowania zestawu obiektów do szablonu
Tre(cid:258)(cid:202) przeznaczona do wy(cid:258)wietlenia na stronie internetowej najcz(cid:218)(cid:258)ciej musi by(cid:202) zdefinio-
wana w widoku. Je(cid:258)li powinna ona by(cid:202) widoczna na ka(cid:285)dej stronie, to najlepszym rozwi(cid:200)za-
niem jest utworzenie procesora kontekstu. Czasami chcemy te(cid:285) pokaza(cid:202) dodatkow(cid:200) tre(cid:258)(cid:202), tak(cid:200)
jak naj(cid:258)wie(cid:285)sze wiadomo(cid:258)ci albo losowy cytat na pewnych wybranych stronach, na przyk(cid:239)ad
stronie startowej lub stronie szczegó(cid:239)owych informacji o obiekcie. W takim przypadku mo(cid:285)na
za(cid:239)adowa(cid:202) potrzebn(cid:200) tre(cid:258)(cid:202) za pomoc(cid:200) znacznika szablonowego { get_objects }, który za-
implementujemy w tej recepturze.
127
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
Przygotowanie
Po raz kolejny zaczniemy prac(cid:218) od aplikacji utils, która powinna by(cid:202) ju(cid:285) zainstalowana i go-
towa do definiowania znaczników szablonowych.
Jak to zrobi(cid:202)
Znaczniki szablonowe sk(cid:239)adaj(cid:200) si(cid:218) z funkcji przetwarzaj(cid:200)cej argumenty przekazane do znacz-
nika i klasy w(cid:218)z(cid:239)owej renderuj(cid:200)cej wynik lub modyfikuj(cid:200)cej kontekst szablonu. Wykonaj zatem
nast(cid:218)puj(cid:200)ce czynno(cid:258)ci:
1. Utwórz nast(cid:218)puj(cid:200)c(cid:200) funkcj(cid:218) przetwarzaj(cid:200)c(cid:200) argumenty znacznika szablonowego:
#utils/templatetags/utility_tags.py
# -*- coding: UTF-8 -*-
from django.db import models
from django import template
register = template.Library()
### ZNACZNIKI ###
@register.tag
def get_objects(parser, token):
Pobiera zbiór obiektów modelu okre(cid:286)lonego przez aplikacj(cid:266) i nazwy modeli.
Sposób u(cid:298)ycia:
{ get_objects [ manager .] method from app_name . model_name
(cid:180)[limit amount ] as var_name }
Przyk(cid:225)ad:
{ get_objects latest_published from people.Person limit 3 as people }
{ get_objects site_objects.all from articles.Article limit 3 as articles }
{ get_objects site_objects.all from articles.Article as articles }
amount = None
try:
tag_name, manager_method, str_from, appmodel, str_limit, amount, str_as,
(cid:180)var_name = token.split_contents()
except ValueError:
try:
tag_name, manager_method, str_from, appmodel, str_as, var_name =
(cid:180)token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, Znacznik get_objects ma
(cid:180)nast(cid:218)puj(cid:200)c(cid:200) sk(cid:239)adni(cid:218): { get_objects [ manager .] method from
(cid:180) app_name . model_name [limit amount ] as var_name }
try:
app_name, model_name = appmodel.split( . )
except ValueError:
raise template.TemplateSyntaxError, Znacznik get_objects wymaga nazwy
(cid:180)aplikacji i modelu rozdzielonych kropk(cid:200).
model = models.get_model(app_name, model_name)
return ObjectsNode(model, manager_method, amount, var_name)
128
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
2. Nast(cid:218)pnie w tym samym pliku utwórz klas(cid:218) w(cid:218)z(cid:239)ow(cid:200):
class ObjectsNode(template.Node):
def __init__(self, model, manager_method, amount, var_name):
self.model = model
self.manager_method = manager_method
self.amount = amount
self.var_name = var_name
def render(self, context):
if . in self.manager_method:
manager, method = self.manager_method.split( . )
else:
manager = _default_manager
method = self.manager_method
qs = getattr(
getattr(self.model, manager),
method,
self.model._default_manager.none,
)()
if self.amount:
amount = template.resolve_variable(self.amount, context)
context[self.var_name] = qs[:amount]
else:
context[self.var_name] = qs
return
Jak to dzia(cid:239)a
Znacznik szablonowy { get_objects } (cid:239)aduje obiekt QuerySet zdefiniowany przez metod(cid:218)
manager z okre(cid:258)lonych aplikacji i modelu, ogranicza wyniki do podanej ilo(cid:258)ci oraz zapisuje
wynik w zmiennej kontekstowej.
Poni(cid:285)ej znajduje si(cid:218) najprostszy przyk(cid:239)ad u(cid:285)ycia utworzonego przez nas znacznika szablono-
wego. (cid:146)aduje on pi(cid:218)(cid:202) artyku(cid:239)ów do dowolnego szablonu:
{ load utility_tags }
{ get_objects all from news.Article limit 5 as latest_articles }
{ for article in latest_articles }
a href= {{ article.get_url_path }} {{ article.title }} /a
{ endfor }
Wykorzystujemy tu metod(cid:218) all domy(cid:258)lnego mened(cid:285)era objects modelu Article. Artyku(cid:239)y
zostan(cid:200) posortowane przez atrybut ordering zdefiniowany w klasie Meta.
W bardziej zaawansowanym przypadku mo(cid:285)na by by(cid:239)o utworzy(cid:202) w(cid:239)asnego mened(cid:285)era z w(cid:239)asn(cid:200)
metod(cid:200) do odpytywania obiektów z bazy danych. Mened(cid:285)er jest interfejsem dostarczaj(cid:200)cym
operacje zapytaniowe na bazie danych do modeli. Ka(cid:285)dy model ma domy(cid:258)lnie przynajmniej
129
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
jednego mened(cid:285)era o nazwie objects. W ramach przyk(cid:239)adu utworzymy model Artist, który
mo(cid:285)e mie(cid:202) status draft lub published, i nowego mened(cid:285)era custom_manager umo(cid:285)liwiaj(cid:200)cego
losowe wybieranie opublikowanych artystów:
#artists/models.py
# -*- coding: UTF-8 -*-
from django.db import models
from django.utils.translation import ugettext_lazy as _
STATUS_CHOICES = (
( draft , _( Szkic )),
( published , _( Opublikowany )),
)
class ArtistManager(models.Manager):
def random_published(self):
return self.filter(status= published ).order_by( ? )
class Artist(models.Model):
# ...
status = models.CharField(_( Status ), max_length=20,
choices=STATUS_CHOICES)
custom_manager = ArtistManager()
Aby za(cid:239)adowa(cid:202) losowego opublikowanego artyst(cid:218), nale(cid:285)y doda(cid:202) poni(cid:285)szy kod do dowolnie
wybranego szablonu:
{ load utility_tags }
{ get_objects custom_manager.random_published from artists.Artist
limit 1 as random_artists }
{ for artist in random_artists }
{{ artist.first_name }} {{ artist.last_name }}
{ endfor }
Przyjrzyjmy si(cid:218) kodowi znacznika szablonowego. W funkcji przetwarzaj(cid:200)cej spodziewany jest
jeden z dwóch formatów: z limitem lub bez limitu. (cid:146)a(cid:241)cuch jest przetwarzany, model zostaje
rozpoznany i sk(cid:239)adniki znacznika szablonowego zostaj(cid:200) przekazane do klasy ObjectNode.
W metodzie render klasy w(cid:218)z(cid:239)owej sprawdzamy nazw(cid:218) mened(cid:285)era i nazw(cid:218) jego metody. Je(cid:258)li
nie jest on zdefiniowany, zostanie u(cid:285)yty domy(cid:258)lny _default_manager, który w wi(cid:218)kszo(cid:258)ci przy-
padków jest taki sam jak objects. Potem wywo(cid:239)ujemy metod(cid:218) mened(cid:285)era i je(cid:258)li metoda ta nie
istnieje, awaryjnie u(cid:285)ywamy pustego obiektu QuerySet. Je(cid:285)eli podany jest limit, okre(cid:258)lamy jego
warto(cid:258)(cid:202) i ograniczamy QuerySet. Na koniec zapisujemy obiekt QuerySet w zmiennej kontekstowej.
Zobacz równie(cid:285)
(cid:81) Receptura „Tworzenie znacznika szablonowego do do(cid:239)(cid:200)czania szablonu, je(cid:258)li istnieje”
(cid:81) Receptura „Tworzenie znacznika szablonowego do przetwarzania tre(cid:258)ci jako szablonu”
(cid:81) Receptura „Tworzenie znacznika szablonowego do modyfikowania parametrów zapyta(cid:241)”
130
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
Tworzenie znacznika szablonowego
do przetwarzania tre(cid:258)ci jako szablonu
W tej recepturze pokazuj(cid:218), jak utworzy(cid:202) znacznik szablonowy o nazwie { parse }, który
umo(cid:285)liwia wstawianie fragmentów szablonów do bazy danych. Jest to przydatne, gdy trzeba
dostarcza(cid:202) inn(cid:200) tre(cid:258)(cid:202) u(cid:285)ytkownikom uwierzytelnionym ni(cid:285) nieuwierzytelnionym, gdy chce si(cid:218)
wy(cid:258)wietla(cid:202) spersonalizowane powitania albo gdy nie chce si(cid:218) wpisywa(cid:202) na sztywno (cid:258)cie(cid:285)ek
do mediów do bazy danych.
Przygotowanie
Jak si(cid:218) pewnie spodziewasz, prac(cid:218) zaczniemy od aplikacji utils, która powinna by(cid:202) ju(cid:285) zain-
stalowana i gotowa do definiowania znaczników szablonowych.
Jak to zrobi(cid:202)
Znaczniki szablonowe sk(cid:239)adaj(cid:200) si(cid:218) z funkcji przetwarzaj(cid:200)cej argumenty przekazane do znacz-
nika i klasy w(cid:218)z(cid:239)owej implementuj(cid:200)cej logik(cid:218) oraz wynik zwracany przez znacznik:
1. Najpierw utwórz nast(cid:218)puj(cid:200)c(cid:200) funkcj(cid:218) przetwarzaj(cid:200)c(cid:200) argumenty znacznika
szablonowego:
#utils/templatetags/utility_tags.py
# -*- coding: UTF-8 -*-
from django import template
register = template.Library()
### ZNACZNIKI ###
@register.tag
def parse(parser, token):
Przetwarza warto(cid:286)(cid:252) jako szablon i j(cid:261) drukuje lub zapisuje w zmiennej.
Sposób u(cid:298)ycia:
{ parse template_value [as variable ] }
Przyk(cid:225)ady:
{ parse object.description }
{ parse header as header }
{ parse {{ MEDIA_URL }}js/ as js_url }
bits = token.split_contents()
tag_name = bits.pop(0)
try:
template_value = bits.pop(0)
var_name = None
if len(bits) == 2:
131
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
bits.pop(0) # usu(cid:276) s(cid:225)owo „as”
var_name = bits.pop(0)
except ValueError:
raise template.TemplateSyntaxError, Znacznik parse ma nast(cid:218)puj(cid:200)c(cid:200)
(cid:180)sk(cid:239)adni(cid:218): { parse template_value [as variable ] }
return ParseNode(template_value, var_name)
2. Nast(cid:218)pnie w tym samym pliku utwórz klas(cid:218) w(cid:218)z(cid:239)ow(cid:200):
class ParseNode(template.Node):
def __init__(self, template_value, var_name):
self.template_value = template_value
self.var_name = var_name
def render(self, context):
template_value = template.resolve_variable(self.template_value, context)
t = template.Template(template_value)
context_vars = {}
for d in list(context):
for var, val in d.items():
context_vars[var] = val
result = t.render(template.RequestContext(context[ request ], context_vars))
if self.var_name:
context[self.var_name] = result
return
return result
Jak to dzia(cid:239)a
Znacznik szablonowy { parse } umo(cid:285)liwia przetwarzanie warto(cid:258)ci jako szablonu i natych-
miastowe jego renderowanie lub zapisanie go jako zmiennej kontekstowej.
Je(cid:258)li mamy obiekt z polem description, które mo(cid:285)e zawiera(cid:202) zmienne szablonowe lub logik(cid:218),
to mo(cid:285)emy go przetwarza(cid:202) i renderowa(cid:202) przy u(cid:285)yciu poni(cid:285)szego kodu:
{ load utility_tags }
{ parse object.description }
Mo(cid:285)na te(cid:285) zdefiniowa(cid:202) warto(cid:258)(cid:202) do przetworzenia przy u(cid:285)yciu (cid:239)a(cid:241)cucha w cudzys(cid:239)owie:
{ load utility_tags }
{ parse {{ STATIC_URL }}site/img/ as img_path }
img src= {{ img_path }}someimage.png alt= /
Spójrzmy na kod naszego znacznika szablonowego. Funkcja przetwarzaj(cid:200)ca sprawdza po kolei
jego argumenty. Najpierw oczekujemy nazwy parse, nast(cid:218)pnie warto(cid:258)ci szablonu, pó(cid:283)niej opcjo-
nalnego s(cid:239)owa as i na ko(cid:241)cu nazwy zmiennej kontekstowej. Warto(cid:258)(cid:202) szablonu i nazwa zmiennej
s(cid:200) przekazywane do klasy ParseNode. Metoda render tej klasy rozwi(cid:200)zuje warto(cid:258)(cid:202) zmiennej sza-
blonowej i tworzy z niej obiekt szablonu. Pó(cid:283)niej renderuje ten szablon ze wszystkimi zmiennymi
kontekstowymi. Je(cid:258)li podana jest nazwa zmiennej, to wynik zostaje zapisany w tej zmiennej.
W przeciwnym razie wynik zostaje od razu wy(cid:258)wietlony.
132
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
Zobacz równie(cid:285)
(cid:81) Receptura „Tworzenie znacznika szablonowego do do(cid:239)(cid:200)czania szablonu,
je(cid:258)li istnieje”
(cid:81) Receptura „Tworzenie znacznika szablonowego do (cid:239)adowania zestawu obiektów
do szablonu”
(cid:81) Receptura „Tworzenie znacznika szablonowego do modyfikowania parametrów
zapyta(cid:241)”
Tworzenie znacznika szablonowego
do modyfikowania parametrów zapyta(cid:241)
System Django ma wygodny w u(cid:285)yciu i elastyczny system do tworzenia kanonicznych i czys-
tych adresów URL za pomoc(cid:200) regu(cid:239) w postaci wyra(cid:285)e(cid:241) regularnych, które dodaje si(cid:218) do pli-
ków konfiguracji URL. Brakuje w nim jednak wbudowanego mechanizmu do zarz(cid:200)dzania pa-
rametrami zapyta(cid:241). Widoki takie jak wyniki wyszukiwania czy filtrowalne listy obiektów musz(cid:200)
przyjmowa(cid:202) parametry pozwalaj(cid:200)ce przegl(cid:200)da(cid:202) przefiltrowane wyniki przy u(cid:285)yciu innego pa-
rametru lub przej(cid:258)(cid:202) do innej strony. W tej recepturze utworzymy znacznik szablonowy o nazwie
{ append_to_query }, umo(cid:285)liwiaj(cid:200)cy dodawanie, zmienianie i usuwanie parametrów bie(cid:285)(cid:200)cego
zapytania.
Przygotowanie
Ponownie prac(cid:218) zaczniemy od aplikacji utils, która powinna by(cid:202) dodana do sekcji INSTALLED_APPS
i zawiera(cid:202) pakiet templatetags.
Ponadto w ustawieniu TEMPLATE_CONTEXT_PROCESSORS powinien by(cid:202) ustawiony procesor kontekstu
request:
#settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
django.contrib.auth.context_processors.auth ,
django.core.context_processors.debug ,
django.core.context_processors.i18n ,
django.core.context_processors.media ,
django.core.context_processors.static ,
django.core.context_processors.tz ,
django.contrib.messages.context_processors.messages ,
django.core.context_processors.request ,
)
133
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
Jak to zrobi(cid:202)
W tym znaczniku wykorzystamy dekorator simple_tag, przetwarzaj(cid:200)cy sk(cid:239)adniki i wymagaj(cid:200)cy
od programisty zdefiniowania tylko funkcji renderuj(cid:200)cej:
#utils/templatetags/utility_tags.py
# -*- coding: UTF-8 -*-
import urllib
from django import template
from django.utils.encoding import force_str
register = template.Library()
### ZNACZNIKI ###
@register.simple_tag(takes_context=True)
def append_to_query(context, **kwargs):
Renderuje odno(cid:286)nik ze zmodyfikowanymi zapytaniami bie(cid:298)(cid:261)cego zapytania.
query_params = context[ request ].GET.copy()
for key, value in kwargs.items():
query_params[key] = value
query_string = u
if len(query_params):
query_string += u ? s urllib.urlencode([
(key, force_str(value)) for (key, value) in query_params.iteritems()
(cid:180)if value
]).replace( , amp; )
return query_string
Jak to dzia(cid:239)a
Znacznik szablonowy { append_to_query } wczytuje bie(cid:285)(cid:200)ce parametry zapytania z podobnego
do s(cid:239)ownika obiektu request.GET typu QueryDict do nowego s(cid:239)ownika o nazwie query_params
i za pomoc(cid:200) p(cid:218)tli przegl(cid:200)da parametry przekazane do znacznika szablonowego, aktualizuj(cid:200)c
warto(cid:258)ci. Nast(cid:218)pnie tworzony jest nowy (cid:239)a(cid:241)cuch zapytania, wszystkie spacje i znaki specjalne
s(cid:200) kodowane do u(cid:285)ytku w adresie URL, a znaki (cid:239)(cid:200)cz(cid:200)ce parametry zapyta(cid:241) zostaj(cid:200) zast(cid:200)pione
encjami. Nowo powsta(cid:239)y (cid:239)a(cid:241)cuch zapytania zostaje zwrócony do szablonu.
Wi(cid:218)cej informacji o obiektach QueryDict mo(cid:285)na znale(cid:283)(cid:202) w oficjalnej dokumentacji Django na
stronie https://docs.djangoproject.com/en/1.6/ref/request-response/#querydict-objects.
Spójrzmy na przyk(cid:239)ad u(cid:285)ycia znacznika { append_to_query }. Je(cid:258)li bie(cid:285)(cid:200)cy adres to http://
127.0.0.1:8000/artists/?category=fine-art page=1, to za pomoc(cid:200) poni(cid:285)szego znacznika sza-
blonowego mo(cid:285)emy wygenerowa(cid:202) odno(cid:258)nik do nast(cid:218)pnej strony:
{ load utility_tags }
a href= { append_to_query page=2 } 2 /a
134
Poleć książkęKup książkęRozdzia(cid:225) 5. • Tworzenie w(cid:225)asnych filtrów i znaczników szablonowych
Oto wynik wyrenderowany przez ten znacznik:
a href= ?category=fine-art amp;page=2 2 /a
A za pomoc(cid:200) poni(cid:285)szego znacznika szablonowego wyrenderujemy odno(cid:258)nik zeruj(cid:200)cy stroni-
cowanie i przechodz(cid:200)cy do innej kategorii:
{ load utility_tags i18n }
a href= { append_to_query category= sculpture page= } { trans Rze(cid:283)ba } /a
Oto wynik wyrenderowany przez ten znacznik:
a href= ?category=sculpture Rze(cid:283)ba /a
Zobacz równie(cid:285)
(cid:81) Receptura „Filtrowanie list obiektów” z rozdzia(cid:239)u 3. „Formularze i widoki”
(cid:81) Receptura „Tworzenie znacznika szablonowego do do(cid:239)(cid:200)czania szablonu, je(cid:258)li istnieje”
(cid:81) Receptura „Tworzenie znacznika szablonowego do (cid:239)adowania zestawu obiektów
do szablonu”
(cid:81) Receptura „Tworzenie znacznika szablonowego do przetwarzania tre(cid:258)ci jako szablonu”
135
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
136
Poleć książkęKup książkęSkorowidz
A
B
administracja kategoriami, 184, 186, 187
adres e-mail, 232
Ajax, 107, 108
algorytm MPTT, 179
Apache, 234
aplikacja
books, 223
bulletin_board, 214
BulletinFeed, 209
cms_extensions, 173
custom_admin, 147
django-ajax-uploader, 108
django-crispy-forms, 70
django-mptt-admin, 184
django-mptt-tree-editor, 186
editorial, 168
email_messages, 62
guerrilla_patches, 221, 222
likes, 103
locations, 93, 149
movies, 74, 100
products, 141
quotes, 66, 111
utils, 85, 91, 120, 229
aplikacje CMS, 164
apphooks, 166
arkusz Excel, 144
arkusze stylów, 95
atrybuty danych HTML5, 93, 94
biblioteka
Fabric, 242
jQuery jqTree, 185
buforowanie warto(cid:258)ci metody, 231
C
CMS, 157
CSS, 169
CSV, comma-separated values, 197
D
data, 42
debugowanie, 226
definiowanie
(cid:258)cie(cid:285)ek wzgl(cid:218)dnych, 23
ustawie(cid:241) aplikacji, 35
dekorator
register.filter, 121
simple_tag, 134
diagnozowania b(cid:239)(cid:218)dów, 199
Django 1.6, 15
Django CMS, 157
dodatek
bpython, 218
IPython, 218
dodawanie
nawigacji, 166
pól, 173
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
do(cid:239)(cid:200)czanie
szablonu, 124, 126
ustawie(cid:241) JavaScript, 90
ustawie(cid:241) lokalnych, 28
zewn(cid:218)trznych zale(cid:285)no(cid:258)ci, 21
domieszka
CreatorMixin, 230
MPTTModel, 182
domieszki do modeli
adresy URL, 39
modyfikowanie dat, 42
obs(cid:239)uga metaznaczników, 43
obs(cid:239)uga relacji generycznych, 46
stosowanie, 38
tworzenie dat, 42
domieszki do wielokrotnego u(cid:285)ytku, 38
dostarczanie danych, 214
dostosowywanie kolumn, 138
E
efektywno(cid:258)(cid:202) instrukcji SQL, 227
eksportowanie danych, 197
element div , 96
encja, 134
F
filtr, 79, 234
humanize_url, 123, 124
szablonowy, 117
adresy URL, 123
pobieranie obiektu, 121
pokazywanie dni, 119
filtrowanie listy
zmian, 144
obiektów, 74
format
CSV, 201
JSON, 201
XML, 207
formatery, 234
formularz MovieFilterForm, 75
formularze, 61
metoda save, 64
obiekt HttpRequest, 61
uk(cid:239)ad, 71
wstawianie map, 149
wybieranie kategorii, 190
wybieranie wielu kategorii, 191
252
funkcja
autocompleteAddress, 152
csv.reader, 199
export_xls, 142
get_git_changeset, 27
get_media_svn_revision, 26
getAddress4search, 151
getattr, 36
mark_safe, 191
slugify, 220, 221
updateAddressFields, 153
updateLatitudeAndLongitude, 152
updateMarker, 152
G
generowanie
kategorii w szablonie, 188
pól, 194
guerrilla patching, 217, 220
hak aplikacji, 165, 166
HTML5, 93
H
I
implementacja
ci(cid:200)g(cid:239)ego przewijania, 100
wid(cid:285)etu polubie(cid:241), 102
importowanie
danych, 197
z pliku CSV, 197
z pliku Excela, 199
z pliku JSON, 201
z pliku XML, 206
plików, 33
indykatory, 92
informacje o
filmach, 198
ignorowanych zasobach, 32
interfejs administracyjny, 184, 186
J
JavaScript, 87
j(cid:218)zyki serwisu, 161
Poleć książkęKup książkękana(cid:239) RSS, 209
kasowanie sesji, 240
kategorie
hierarchiczne, 181
importowe, 34
klasa
BulletinFeed, 213
BulletinFilterForm, 211
ChangeList, 224
CMSAttachMenu, 168
CMSPluginBase, 169
Command, 199
CreationModificationDateMixin, 43
CSS, 169
CSSExtension, 173
CSSExtensionToolbar, 176
domieszkowa, 38
FilterableListView, 85
GroupAdmin, 148
img-full-width, 96
Meta, 216
ModelResource, 216
MoviesApphook, 165
MoviesMenu, 167
NavigationNode, 168
PageExtension, 176
PhotoFilter, 146
ProductAdmin, 143
SimpleListFilter, 145
TreeForeignKey, 183
TreeManyToManyField, 183
UserAdmin, 148
View, 83
klasy w(cid:218)z(cid:239)owe, 129
klucz
Api, 215
obcy, 58, 216
kodowanie
LATIN1, 29
UTF-8, 29
kolejno(cid:258)(cid:202) importowania plików, 33
komponowanie widoków, 83
konfiguracja
menu stron, 161
MySQL, 29
rejestratora dziennikowego, 233
Skorowidz
K
konstrukcja {{ child.cssextension }}, 178
kontrolki stronicowania, 82
konwertowanie aplikacji, 164
krotka, 143
LATIN1, 29
layout, 71
lista
kategorii, 79
krotek, 143
obiektów, 74
pól wyboru, 191
zmian, 138, 143, 144
listy stronicowane, 80
L
(cid:146)
(cid:239)adowanie zestawu obiektów, 127
M
mapa, 149, 155
menu stron, 161
metaznacznik, 43, 166
metoda
as_view(), 83
feed_url, 213
GET, 83
get_absolute_url(), 39
get_object, 213
get_page, 83get_queryset_and_facets, 83, 85
get_thumbnail_picture_url, 69
get_translated_list, 225
get_url(), 41
get_url_path(), 41
handle, 204
image.save, 205
POST, 83
render, 130
request.get, 205
response.get, 208
save, 64, 110
save(), 43
save_page, 208
title, 213
migracja South, 55, 57
253
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
model
administracji Django, 223
Book, 223
Bulletin, 210
Category, 181
CSSExtension, 174
Movie, 181, 182
Track, 203
modelowanie panelu administracyjnego, 137
modu(cid:239)
mod_wsgi, 234
utils, 227
modu(cid:239)owa budowa klasy, 83
modyfikator menu, 175
modyfikowanie parametrów zapyta(cid:241), 133
monkey patching, 217, 220, 224
N
narz(cid:218)dzia diagnostyczne, 227
narz(cid:218)dzie
easy_install, 17
pip, 16, 20
South, 58
ThreadLocalMiddleware, 229
virtualenv, 16
Virtualmin, 234, 235
nawigacja, 166
O
obiekt
HttpRequest, 61, 63, 229, 230
HttpResponse, 143
jScroll, 102
QueryDict, 134
QuerySet, 130, 146
request, 62, 63
obiekty (cid:258)ródliniowe, 139
obs(cid:239)uga
metaznaczników, 43
pól wieloj(cid:218)zycznych, 50
rejestracji danych, 232
relacji generycznych, 46
opcje administracyjne, 174
254
P
pakiet
panel
commands, 200
utils, 46, 50
xlrd, 200
administracyjny, 137
Virtualmin, 235
pasek narz(cid:218)dzi debugowania, 226
plik
.bash_profile, 33
.gitignore, 32
.htaccess, 241
.htaccess_live, 241
.htaccess_under_construction, 241
__init__.py, 104
admin.py, 139, 142, 145, 147
app_settings.py, 35
base.html, 88, 161
base.py, 39
base_simple.html, 89
cms_app.py, 165
cms_plugins.py, 169
cms_toolbar.py, 174, 176
fabfile.py, 242
feeds.py, 211
fields.py, 50, 192
forms.py, 62, 190
likes_tags.py, 104
local_settings.py, 28, 31
locating.js, 151
log.py, 232
manage.py, 220
menu.py, 167
middleware.py, 229
misc.py, 27, 227
models.py, 35, 38, 42, 46, 181
my.conf, 29
myproject.wsgi, 241
requirements.txt, 56
settings.py, 23, 36, 226
urls.py, 97
utility_tags.py, 120, 122
views.py, 63, 67
pliki
CSV, 197
Excela, 201
JSON, 201
Poleć książkęKup książkęprojektu, 18
skompilowane, 32
szablonowe, 88
XML, 206
pola wieloj(cid:218)zyczne, 50
pole
pojedynczego wyboru, 190
wyboru kategorii, 191
pow(cid:239)oka
Django, 218
Pythona, 220
procedury obs(cid:239)ugowe, 234
program, Patrz narz(cid:218)dzie
przegl(cid:200)danie w(cid:218)z(cid:239)ów, 208
przetwarzanie tre(cid:258)ci, 131
przewijanie ci(cid:200)g(cid:239)e, 100
R
raport o b(cid:239)(cid:218)dach, 232
rejestratory, 234
relacje generyczne, 46
repozytorium, 225
responsywny projekt, 70
S
sekcja
body , 90
head , 90
serwer Apache, 234
skrypt, 98, 101, Patrz tak(cid:285)e plik
skrypt Fabric, 242, 247, 248
skryptozak(cid:239)adka, 226
s(cid:239)ownik, 134
stos, 225
stronicowanie, 80, 81
strony CMS-a, 173
struktura
bazy danych, 37
plików projektu, 18
struktury hierarchiczne, 179
system
Git, 26, 32
Subversion, 25, 30
szkieletowy Bootstrap 3, 79
w(cid:239)asny migracji, 57
szablon, 55, 68, 87, 193, 212
base.html, 158
Skorowidz
default.html, 160
editorial_content.html, 171
magazine.html, 170, 172
settings.js, 92
start.html, 160
szablony aplikacji django-crispy-forms, 74
szczegó(cid:239)y obiektu, 97
(cid:165)
(cid:258)cie(cid:285)ka
picture_path, 115
wzgl(cid:218)dna, 23
(cid:258)rodowisko wirtualne, 16
T
technologia Ajax, 107, 108
tryb DEBUG, 225
tworzenie
czynno(cid:258)ci administracyjnych, 141
domieszek do modeli, 39, 42, 46
filtrów, 117
filtrów listy zmian, 144
interfejsu admnistracyjnego, 184
kana(cid:239)ów RSS, 209
kategorii hierarchicznych, 181
klasy w(cid:218)z(cid:239)owej, 132
klucza, 215
przyjaznych adresów, 220
responsywnych projektów, 70
skryptu wdra(cid:285)ania, 241
struktury plików, 18
ustawie(cid:241) lokalnych, 28
wtyczki, 168
znaczników, 117
U
uk(cid:239)ad formularza, 71
us(cid:239)uga Tastypie, 214
ustawienia
administracyjne, 147
JavaScript, 90
lokalne, 28
usuwanie skompilowanych plików, 32
UTF-8, 29
u(cid:285)ycie
metody save, 64
migracji South, 55
255
Poleć książkęKup książkęAplikacje internetowe z Django. Najlepsze receptury
XPath, 209
X
Z
zale(cid:285)no(cid:258)ci
projektu, 21
zewn(cid:218)trzne, 21
zamienianie ustawie(cid:241) administracyjnych, 147
zarz(cid:200)dzanie
listami stronicowanymi, 80
tre(cid:258)ci(cid:200), 157
zale(cid:285)no(cid:258)ciami projektu, 20
zast(cid:218)powanie modelu administracji, 222
zmienianie klucza obcego, 58
zmienna
DJANGO_SETTINGS_MODULE, 220
EXTERNAL_APPS_PATH, 23
EXTERNAL_LIBS_PATH, 23
PROJECT_PATH, 23
STATIC_URL, 25, 26
zmienne
znacznik
kontekstowe szablonu, 228
lokalne, 225
{ append_to_query }, 82, 133, 134
{ get_objects }, 129
{ include }, 126
{ like_widget }, 104
{ like_widget for object }, 107
{ parse }, 132
{ placeholder }, 161
{ recursetree }, 188
{ show_menu_below_id }, 161, 163
{ static_placeholder }, 161
znacznik { try_to_include }, 125, 126
znacznik szablonowy, 77, 117
do(cid:239)(cid:200)czanie szablonu, 124
(cid:239)adowanie zestawu obiektów, 127
modyfikowanie parametrów zapyta(cid:241), 133
przetwarzanie tre(cid:258)ci, 131
znak @, 73
W
warto(cid:258)(cid:202) zmiennej STATIC_URL, 25, 26
wdra(cid:285)anie aplikacji, 234
w (cid:258)rodowisku produkcyjnym, 246
w (cid:258)rodowisku rozwojowym, 243
w (cid:258)rodowisku testowym, 244
widok, 61, 83
MovieListView, 83
render_js, 91
wid(cid:285)et
CheckboxSelectMultiple, 195
Like, 127
polubie(cid:241), 102
wysy(cid:239)ania plików, 109, 112
wieloj(cid:218)zyczne pole
tekstowe, 50
znakowe, 50
w(cid:239)asno(cid:258)(cid:202)
ignore, 30
layout, 71
list_display, 141
short_description, 141
wspó(cid:239)rz(cid:218)dne geograficzne, 149
wstawianie map, 149
wtyczka, 168
EditorialContent, 169
jScroll, 100
wybieranie kategorii, 190, 191
wyskakuj(cid:200)ce okienko, 97
wysy(cid:239)anie
obrazów, 66
plików, 113
raportów o b(cid:239)(cid:218)dach, 232
256
Poleć książkęKup książkę
Pobierz darmowy fragment (pdf)