Django
Szablony
Szukaj…
Zmienne
Dostęp do zmiennych podanych w kontekście widoku można uzyskać za pomocą notacji z podwójnym nawiasiem klamrowym:
W twoich views.py
:
class UserView(TemplateView):
""" Supply the request user object to the template """
template_name = "user.html"
def get_context_data(self, **kwargs):
context = super(UserView, self).get_context_data(**kwargs)
context.update(user=self.request.user)
return context
W user.html
:
<h1>{{ user.username }}</h1>
<div class="email">{{ user.email }}</div>
Dostęp do notacji kropkowej:
- właściwościami obiektu, np.
user.username
będzie{{ user.username }}
- wyszukiwania w słowniku, np.
request.GET["search"]
to{{ request.GET.search }}
- metodami bez argumentów, np.
users.count()
będzie{{ user.count }}
Zmienne szablonu nie mogą uzyskać dostępu do metod pobierających argumenty.
Zmienne można również testować i zapętlać:
{% if user.is_authenticated %}
{% for item in menu %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{% endfor %}
{% else %}
<li><a href="{% url 'login' %}">Login</a>
{% endif %}
Adresy URL są dostępne w formacie {% url 'name' %}
, gdzie nazwy odpowiadają nazwom w twoim urls.py
{% url 'login' %}
- prawdopodobnie będzie renderowany jako /accounts/login/
{% url 'user_profile' user.id %}
- Argumenty adresów URL są dostarczane w kolejności
{% url next %}
- adresy URL mogą być zmiennymi
Szablony w widokach klasowych
Możesz przekazać dane do szablonu w zmiennej niestandardowej.
W twoich views.py
:
from django.views.generic import TemplateView
from MyProject.myapp.models import Item
class ItemView(TemplateView):
template_name = "item.html"
def items(self):
""" Get all Items """
return Item.objects.all()
def certain_items(self):
""" Get certain Items """
return Item.objects.filter(model_field="certain")
def categories(self):
""" Get categories related to this Item """
return Item.objects.get(slug=self.kwargs['slug']).categories.all()
Prosta lista w item.html
:
{% for item in view.items %}
<ul>
<li>{{ item }}</li>
</ul>
{% endfor %}
Możesz także odzyskać dodatkowe właściwości danych.
Zakładając, że Twój model Item
ma pole name
:
{% for item in view.certain_items %}
<ul>
<li>{{ item.name }}</li>
</ul>
{% endfor %}
Szablony w widokach opartych na funkcjach
Możesz użyć szablonu w widoku opartym na funkcjach w następujący sposób:
from django.shortcuts import render
def view(request):
return render(request, "template.html")
Jeśli chcesz użyć zmiennych szablonu, możesz to zrobić w następujący sposób:
from django.shortcuts import render
def view(request):
context = {"var1": True, "var2": "foo"}
return render(request, "template.html", context=context)
Następnie w template.html
możesz odwoływać się do swoich zmiennych w następujący sposób:
<html>
{% if var1 %}
<h1>{{ var2 }}</h1>
{% endif %}
</html>
Filtry szablonów
System szablonów Django ma wbudowane znaczniki i filtry , które są funkcjami wewnątrz szablonu, aby renderować zawartość w określony sposób. Za pomocą potoków można określić wiele filtrów, a filtry mogą mieć argumenty, podobnie jak w składni zmiennej.
{{ "MAINROAD 3222"|lower }} # mainroad 3222
{{ 10|add:15}} # 25
{{ "super"|add:"glue" }} # superglue
{{ "A7"|add:"00" }} # A700
{{ myDate | date:"D d M Y"}} # Wed 20 Jul 2016
Listę dostępnych wbudowanych filtrów można znaleźć na stronie https://docs.djangoproject.com/en/dev/ref/templates/builtins/#ref-templates-builtins-filters .
Tworzenie niestandardowych filtrów
Aby dodać własne filtry szablonów, utwórz folder o nazwie templatetags
w folderze aplikacji. Następnie dodaj __init__.py
i plik, który będzie zawierał filtry:
#/myapp/templatetags/filters.py
from django import template
register = template.Library()
@register.filter(name='tostring')
def to_string(value):
return str(value)
Aby faktycznie użyć filtra, musisz go załadować do szablonu:
#templates/mytemplate.html
{% load filters %}
{% if customer_id|tostring = customer %} Welcome back {% endif%}
Wydziwianie
Mimo że filtry na pierwszy rzut oka wydają się proste, pozwala robić fajne rzeczy:
{% for x in ""|ljust:"20" %}Hello World!{% endfor %} # Hello World!Hello World!Hel...
{{ user.name.split|join:"_" }} ## replaces whitespace with '_'
Zobacz także tagi szablonów, aby uzyskać więcej informacji.
Zapobiegaj wywoływaniu wrażliwych metod w szablonach
Gdy obiekt jest wystawiony na kontekst szablonu, dostępne są jego metody bez argumentów. Jest to przydatne, gdy funkcje te są „pobierające”. Ale może to być niebezpieczne, jeśli metody te zmienią niektóre dane lub wywołają pewne skutki uboczne. Chociaż prawdopodobnie ufasz twórcy szablonów, może on nie być świadomy skutków ubocznych funkcji lub pomyśleć, że przez pomyłkę nazwij niewłaściwy atrybut.
Biorąc pod uwagę następujący model:
class Foobar(models.Model):
points_credit = models.IntegerField()
def credit_points(self, nb_points=1):
"""Credit points and return the new points credit value."""
self.points_credit = F('points_credit') + nb_points
self.save(update_fields=['points_credit'])
return self.points_credit
Jeśli napiszesz to przez pomyłkę w szablonie:
You have {{ foobar.credit_points }} points!
To zwiększy liczbę punktów przy każdym wywołaniu szablonu. I możesz nawet tego nie zauważyć.
Aby temu zapobiec, należy ustawić atrybut alters_data
na True
na metody wywołujące skutki uboczne. Uniemożliwi to wywołanie ich z szablonu.
def credit_points(self, nb_points=1):
"""Credit points and return the new points credit value."""
self.points_credit = F('points_credit') + nb_points
self.save(update_fields=['points_credit'])
return self.points_credit
credit_points.alters_data = True
Zastosowanie {% rozszerza%}, {% zawiera%} i {% bloki%}
streszczenie
{% extends%} : deklaruje szablon podany jako argument jako element nadrzędny bieżącego szablonu. Zastosowanie:
{% extends 'parent_template.html' %}
.{% block%} {% endblock%} : Służy do definiowania sekcji w szablonach, dzięki czemu jeśli inny szablon rozszerzy ten szablon, będzie mógł zastąpić napisany w nim kod HTML. Bloki są identyfikowane według ich nazwy. Zastosowanie:
{% block content %} <html_code> {% endblock %}
.{% include%} : spowoduje wstawienie szablonu do bieżącego. Pamiętaj, że dołączony szablon otrzyma kontekst żądania i możesz również nadać mu zmienne niestandardowe. Podstawowe użycie:
{% include 'template_name.html' %}
, użycie ze zmiennymi:{% include 'template_name.html' with variable='value' variable2=8 %}
Przewodnik
Załóżmy, że budujesz swój kod front-end z wspólnymi układami dla całego kodu i nie chcesz powtarzać kodu dla każdego szablonu. Django daje Ci do tego wbudowane tagi.
Załóżmy, że mamy jedną stronę blogu z 3 szablonami o tym samym układzie:
project_directory
..
templates
front-page.html
blogs.html
blog-detail.html
1) Zdefiniuj plik base.html
,
<html>
<head>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
2) Rozszerz go w blog.html
np.
{% extends 'base.html' %}
{% block content %}
# write your blog related code here
{% endblock %}
# None of the code written here will be added to the template
Tutaj rozszerzyliśmy układ podstawowy, więc układ HTML jest teraz dostępny w pliku blog.html
Pojęcie { % block %}
to dziedziczenie szablonów, które pozwala zbudować podstawowy szablon „szkieletowy”, który zawiera wszystkie typowe elementy twojego witryna i definiuje bloki, które szablony potomne mogą zastąpić.
3) Teraz załóżmy, że wszystkie 3 szablony mają również ten sam div HTML, który definiuje niektóre popularne posty. Zamiast pisać 3 razy, stwórz jeden nowy szablon posts.html
.
blog.html
{% extends 'base.html' %}
{% block content %}
# write your blog related code here
{% include 'posts.html' %} # includes posts.html in blog.html file without passing any data
<!-- or -->
{% include 'posts.html' with posts=postdata %} # includes posts.html in blog.html file with passing posts data which is context of view function returns.
{% endblock %}