Sprawdź wszystkie części serii Sekrety Django Templates:
- Sekrety Django Templates #1. Html na sterydach
- Sekrety Django Templates #2. Nieznane tagi, które ułatwią Ci obsługę list
Szablony Django (Django templates) to pliki tekstowe, zawierające najczęściej kod html, do których możemy wstrzyknąć dodatkowe zmienne przekazane z widoku.
Dzisiaj postaram się pokazać Ci, jak dokładnie wygląda wymiana informacji pomiędzy tymi szablonami a widokami i zaprezentuję kilka ciekawych sztuczek, dzięki którym możesz uprościć swój kod.
Na potrzeby tego artykułu stworzyłam prosty widok zwracający informację o dwóch studentach:
class StudentsView(View):
def get(self, request):
student_1 = {'name': 'John', 'surname': 'Black', 'grade':5.0}
student_2 = {'name': 'Mary', 'surname': 'White', 'grade': 3.5}
context = {
'student_1': student_1,
'student_2': student_2
}
return render(request, 'students.html', context=context)
Co możemy z nim zrobić?
1. Zmienne
Jeśli chcesz odczytać wartość zmiennej przekazanej do szablonu, podaj jej nazwę w podwójnych nawiasach klamrowych: {{ .. }}
.
Zacznij od stworzenia szablonu students.html
i uzupełnij go w następujący sposób:
Student 1 : {{ student_1 }}
Student 2 : {{ student_2 }}
W przeglądarce powinieneś zobaczyć coś takiego:
Student 1: {'name': 'John', 'surname': 'Black', 'grade': 5.0}
Student 2: {'name': 'Mary', 'surname': 'White', 'grade': 3.5}
Brawo! Django zwróciło całą zawartość wywołanych obiektów.
No to lecimy dalej.
Słowniki
Aby odczytać wybrane pola słownika (dict), należy po kropce podać nazwę odpowiedniego klucza:
Student 1:
Imię: {{ student_1.name }}, Nazwisko: {{ student_1.surname }}
Powyższy kod zwróci następujący widok:
Student 1:
Imię: John, Nazwisko: Black
W ten sposób możesz odwoływać się do dowolnych kluczy i wyświetlać powiązane z nimi wartości.
Obiekty
Aby odwołać się do atrybutów obiektów klas, należy postąpić tak samo i również wykorzystać notację kropki (dot notation).
Sprawdź więc teorię i zmodyfikuj nieco widok, tworząc trzeciego studenta i przekazując go do kontekstu:
student_3 = Student(name='Mike', surname='Doe', grade=4.5)
context = {
...
'student_3': student_3
}
Brakuje jeszcze definicji nowej klasy Student
. W najprostszej implementacji może ona wyglądać tak:
class Student:
def __init__(self, name, surname, grade):
self.name = name
self.surname = surname
self.grade = grade
Domyślasz się juz, jak będzie wyglądał nowy widok? Myślę, że tak. 😃
Student 3:
Imię: {{ student_3.name}}, Nazwisko: {{ student_3.surname }}
Teraz nie ma już innej możliwości, jak tylko podejrzeć dane nowego studenta:
Student 3:
Imię: Mike, Nazwisko: Doe
Proste, prawda?😉
No to czas połączyć studentów w jedną całość i stworzyć z nich listę.
Listy
Na początek mała modyfikacja widoku i nowa zmienna przekazana do kontekstu:
students_list = [student_1, student_2, student_3]
context = {
...
'students_list': students_list
}
I tutaj czeka nas coś zaskakującego. Jeśli w kodzie Pythona chciałbyś pobrać pierwszego studenta z listy, użyłbyś poniższego zapisu:
students_list[0]
Niestety w przypadku szablonów twórcy Django nagięli nieco własne zasady i zastąpili nawiasy kwadratowe … kropką! 😯
Stąd też odwołanie się do pierwszego elementu listy będzie wyglądało odrobinę inaczej, niż mogłoby się wydawać:
Pierwszy student z listy: {{ students_list.0 }}
Drugi student z listy: {{ students_list.1 }}
W rezultacie powinieneś zobaczyć poniższy wynik:
Pierwszy student z listy:
{'name': 'John', 'surname': 'Black', 'grade': 5.0}
Drugi student z listy:
{'name': 'Mary', 'surname': 'White', 'grade': 3.5}
Dziwne? Tak, mi też na początku wydawało mi się to niezbyt logiczne, ale jak się nie ma co się lubi… to lepiej docenić to, co się ma.
A teraz ciekawostka!
Jak myślisz, co się stanie, kiedy nazwa Twojej zmiennej będzie zaczynać się od podkreślnika?
Próba wywołania w szablonie takiej zmiennej: {{ _student_4 }}
zakończy się poniższym błędem:

Dlaczego?
Zgodnie z konwencją Pythona zmienne rozpoczynające się podkreślnikiem uważane są za prywatne i nie mogą być dostępne z zewnątrz. Zwracaj więc uwagę na to, jak nazywasz swoje zmienne.
2. Tagi
Oprócz obsługi zmiennych Django umożliwia też sterowanie logiką wyświetlanych w szablonach danych. Służą do tego tzw. tagi, które wywołuje się z wykorzystaniem symbolu: {% ... %}
, podając wewnątrz nazwę odpowiedniego znacznika.
Niektóre tagi działają tylko w obrębie wybranej sekcji szablonu i wywagają znacznika zamykającego: {% end... %}
.
Może na razie wydaje Ci się to nieco zagmatwane, ale spokojnie. Zaraz wszystko wyjaśnię.
Iteracja po liście {% for ... in ... %}
Wróć więc do listy studentów i spróbuj wyświetlić informację o każdym z nich w nowym wierszu. Przyda się do tego tag{% for <em>...</em> in <em>...</em> %}
,pozwalający iterować po liście podanej jako drugi parametr (po słowie in
).
Jako pierwszy parametr możesz podać dowolną nazwę, która będzie służyła jako referencja do aktualnie przetwarzanego elementu listy.
<ul>
{% for student in students_list %}
<li>{{ student.name }} {{ student.surname }}</li>
{% endfor %}
</ul>
Powyższy kod wygeneruje następujący widok:
- John Black
- Mary White
- Mike Doe
Jak widać potrzebny był też tag zamykający {% endfor %}
. Dzięki niemu Django wie, które elementy szablonu musi wygenerować dla każdego elementy listy.
Instrukcje warunkowe {% if ... elif ... else %}
A teraz czas na instrukcje warunkowe. Sprawdźmy więc oceny naszych studentów. Potrzebne będą do tego tagi: {% if ... %}, {% elif %}, {% else %}
oraz zamykający {% endif %}
<ul>
{% for student in students_list %}
<li>
{{ student.name }} {{ student.surname }}
{% if student.grade == 5.0 %} - Kujon
{% elif student.grade > 4 %} - Tak trzymaj!
{% else %} - Pora na naukę!
{% endif %}
</li>
{% endfor %}
</ul>
Wewnątrz dwóch pierwszych tagów podaliśmy warunki, które muszą być spełnione, aby wyświetlił się odpowiedni komunikat. Tag {% else %}
wyłapuje wszystkie pozostałe przypadki.
Po odświeżeniu strony powinieneś otrzymać coś takiego:
- John Black – Kujon
- Mary White – Pora na naukę!
- Mike Doe – Tak trzymaj!
W zależności od Twoich potrzeb możesz użyć tylu tagów {% elif %},
ile potrzebujesz. Z kolei zarówno {% elif %}
, jak i {% else %}
są opcjonalne i nie musisz ich używać, jeśli są zbędne.
Jednocześnie pamiętaj o znaczniku zamykającym: {% endif %}.
Dziedziczenie i nadpisywanie szablonów
Oprócz list i instrukcji warunkowych, jednymi z najczęściej używanych tagów są te, które umożliwiają rozszerzanie lub nadpisywanie szablonów. Zaliczają się do nich następujące znaczniki:
{% block ... %} {% endblock %}
– opakowanie fragmentu szablonu tymi tagami pozwala na nadpisanie jego zawartości w innych szablonach,{% extends ... %}
– pozwala na wywołanie szablonu nadrzędnego w dziedziczącym z niego i ewentualne nadpisanie jego zawartości,{% include %}
– umożliwia wstrzyknięcie szablonu wewnątrz innego,{% load %}
– pozwala ładować dodatkowe tagi – własne lub z zewnętrznych bibliotek.
Poza kilkoma wymienionymi tagami Django udostępnia jeszcze wiele interesujących znaczników. Pełną listę możesz znaleźć w oficjalnej dokumentacji.
3. Filtry
Na koniec w kilku słowach chciałabym opisać trzeci mechanizm Django templates – filtry. Oferują one rozmaite przekształcenia wyświetlanej wartości wstrzykiwanych zmiennych, a wywołuje się je w następujący sposób:
{{ student1.name | filter_name }}
Lista dostępnych filtrów jest naprawdę spora, a możesz ją znaleźć oczywiście w oficjalnej dokumentacji. Pozwolę sobie pokazać jedynie kilka wybranych przykładów.
Zacznijmy od dodania kilku pól do zmiennej student_1
:
student_1 = {
'name': 'John',
'surname': 'Black',
'grade': 5.0,
'birth_date': datetime(2000, 10, 27, 16, 25),
'has_graduated': True,
'bio': 'Very smart n and intelligent.',
'scholarship': ''
}
Czas przekonać się, co potrafią filtry szablonów Django!
Operacje na ciągach znaków
lower
– najprostsza operacja, czyli zamiana wszystkich liter na małe.
Przykład:{{ student_1.name | lower }}
➜ john.upper
– sytuacja odwrotna – zamiana wszystkich liter na wielkie.
Przykład:{{ student_1.name | upper }}
➜ JOHNtitle
– każde słowo podanego stringa rozpocznie się wielką literą.
Przykład:{{ student_1.bio | title }}
➜ Very Smart And Intelligent.slice
– wycina znaki z zakresu indeksów podanych w parametrze.
Przykład:{{ student_1.bio | slice:"5:16" }}
➜ smart andtruncatechars
– ucina stringa do podanej ilości znaków i dostawia wielokropek, który jest traktowany jako dodatkowy znak.
Przykład:{{ student_1.bio | truncatechars:7 }}
➜ Very s…truncatewords
– ucina ciąg znaków do podanej ilości słów i dostawia wielokropek.
Przykład:{{ student_1.bio | truncatewords:2 }}
➜ Very smart …linebreaksbr
– jeśli string zawiera znak końca linii ‘n’, to zostanie on zamieniony na odpowiedni znacznik html: <br>.
Przykład dla wartościbio = 'Very smart n and intelligent.':
{{ student_1.bio | linebreaksbr }}
➜ Very smart and intelligent
Formatowanie daty / godziny
date
– pozwala na wyświetlenie daty w dowolnym formacie.
Przykład:{{ student_1.birth_date | date:"d/m/Y" }}
➜ 27/10/2000time
– pozwala na wyświetlenie godziny w dowolnym formacie.
Przykład:{{ student_1.birth_date | time:"H:i" }}
➜ 16:25
Wszystkie dostępne formaty daty i godziny znajdziesz tutaj.
Wartości puste i domyślne
default
– jeśli podana zmienna będzie nullem lub pustym stringiem, można ustawić jej wartość domyślną.
Przykład:{{ student_1.scholarship | default:"Brak" }} ➜ Brak
yesno
– w przypadku wartości typu boolean można nadać im własne etykiety.
Przykład:{{ student_1.has_graduated | yesno:"Tak,Nie" }} ➜ Tak
To zaledwie ułamek wszystkich możliwości filtrów, ale jak widać są one naprawdę ogromne.
Podsumowanie
Mam nadzieję, że udało mi się pokazać Ci jak wiele tajemnic kryją w sobie szablony Django. Odpowiednie wykorzystanie tagów i filtrów często pozwala zawrzeć skomplikowaną logikę w kilku liniach kodu.
Masz jakieś pytania albo wątpliwości? Podziel się swoim doświadczeniem w komentarzu!
I pozostań z nami, bo już niedługo kolejne artykuły, w których postaramy się odkryć jeszcze więcej sekretów Django Templates.
Sprawdź wszystkie części serii Sekrety Django Templates:
- Sekrety Django Templates #1. Html na sterydach
- Sekrety Django Templates #2. Nieznane tagi, które ułatwią Ci obsługę list