Video link: https://www.bilibili.com/video/BV1vK4y1o7jH
1. Template Layer - Variables and Tags#
Variables#
- Python variables can be encapsulated in a dictionary in the view function and passed to the template.
Example:
def xxx_view(request):
dic = {
"variable1": "value1",
"variable2": "value2",
}
return render(request, 'xxx.html', dic)
- Data types that can be passed to the template:
str - string int - integer
list - array tuple - tuple
dict - dictionary func - method
obj - instantiated object
- Using variable syntax in the template:
- {{ variable_name }}
- {{ variable_name.index }}
- {{ variable_name.key }}
- {{ object.method }}
- {{ function_name }}
- Demonstration:
http://127.0.0.1:8000/test_html_param
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('test_html', views.test_html)
]
# mysite1/mysite1/views.py
def test_html_param(request):
dic = {}
dic['int'] = 88
dic['str'] = 'peng'
dic['lst'] = ['Tom', 'Jack', 'Lily']
dic['dict'] = {'a':9, 'b':8}
dic['func'] = say_hi
dic['class_obj'] = Dog()
dic['script'] = '<script>alert(1111)</script>'
return render(request, 'test_html_param.html', dic)
def say_hi():
return 'hahaha'
class Dog:
def say(self):
return 'wangwang'
# mysite1/templates/test_html_param.html
<h3>int is {{ int|add:"2" }}</h3>
<h3>str is {{ str|upper }}</h3>
<h3>lst is {{ lst }}</h3>
<h3>lst is {{ lst.0 }}</h3>
<h3>dict is {{ dict }}</h3>
<h3>dict['a'] is {{ dict.a }}</h3>
<h3>function is {{ func }}</h3>
<h3>class_obj is {{ class_obj.say }}</h3>
<h3>script is {{ script|safe }}</h3>
Tags#
Template Tags
- Purpose: Embed some server-side functionality into the template, such as flow control, etc.
- Tag syntax:
{% tag %}
...
{% endtag %}
if Tag#
- Syntax:
{% if condition_expression1 %}
...
{% elif condition_expression2 %}
...
{% elif condition_expression3 %}
...
{% else %}
...
{% endif %} - Needs an end tag
- Note:
- The operators that can be used in the if condition expression are ==, !=, <, >, <=, >=, in, not in, is, is not, not, and, or.
- Using actual parentheses in if tags is invalid syntax. If you need them to indicate precedence, you should use nested if tags.
Official documentation: https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#if
- Demonstration:
http://127.0.0.1:8000/test_if_for
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('test_if_for', views.test_if_for),
]
# mysite1/mysite1/views.py
def test_if_for(request):
dic = {}
dic['x'] = 20
dic['lst'] = ['Tom', 'Jack', 'Lily']
return render(request, 'test_if_for.html', dic)
# mysite1/templates/test_if_for.html
{% if x > 10 %}
The weather is nice today
{% else %}
The weather is very nice today
{% endif %}
<br>
{% for name in lst %}
{% if forloop.first %} &&&&& {% endif %}
<p> {{ forloop.counter }} {{ name }}</p>
{% if forloop.last %} ===== {% endif %}
{% empty %}
No data available
{% endfor %}
-
Template Tag - if Tag - Exercise
Write a simple calculator page that can perform basic addition, subtraction, multiplication, and division calculations on the server side (needs to remember the user's last input state and dropdown selection state).
-
Frontend reference code:
-
Demonstration:
http://127.0.0.1:8000/mycal
# mysite1/mysite1/urls.py urlpatterns = [ ... path('mycal', views.test_mycal), ] # mysite1/mysite1/views.py def test_mycal(request): if request.method == 'GET': return render(request, 'mycal.html') elif request.method == 'POST': # Handle calculation x = int(request.POST['x']) y = int(request.POST['y']) op = request.POST['op'] result = 0 if op == 'add': result = x + y elif op == 'sub': result = x - y elif op == 'mul': result = x * y elif op == 'div': result = x / y # dic={'x':x, 'y':y, 'op':op} return render(request, 'mycal.html', locals()) # locals method - encapsulates local variables into a dictionary (Python built-in method) # mysite1/templates/mycal.html <form action='/mycal' method='post'> <input type='text' name="x" value="{{ x }}"> <select name='op'> <option value="add" {% if op == 'add' %}selected{% endif %} > +Add</option> # ☆ Record op state, option selected attribute, used if tag <option value="sub" {% if op == 'sub' %}selected{% endif %}> -Subtract</option> <option value="mul" {% if op == 'mul' %}selected{% endif %}> *Multiply</option> <option value="div" {% if op == 'div' %}selected{% endif %}> /Divide</option> </select> <input type='text' name="y" value="{{ y }}"> = <span>{{ result }}</span> <div><input type="submit" value='Start Calculation'></div> </form>
-
for Tag#
-
Syntax:
{% for variable in iterable %} ... loop statement {% empty %} ... statement to fill when the iterable has no data {% endfor %}
Official documentation: https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#for
-
Built-in variable - forloop
- Demonstration:
http://127.0.0.1:8000/test_if_for
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('test_if_for', views.test_if_for),
]
# mysite1/mysite1/views.py
def test_if_for(request):
dic = {}
dic['lst'] = ['Tom', 'Jack', 'Lily']
return render(request, 'test_if_for.html', dic)
# mysite1/templates/test_if_for.html
{% for name in lst %}
{% if forloop.first %} &&&&& {% endif %}
<p> {{ forloop.counter }} {{ name }}</p>
{% if forloop.last %} ===== {% endif %}
{% empty %}
No data available
{% endfor %}
Summary#
- Variable calling - dot notation
- Tag syntax {% raw %}{% tag %} {% endtag %}{% endraw %}
2. Template Layer - Filters and Inheritance#
Filters#
- Definition: Process the value of a variable when outputting the variable.
- Purpose: You can change the output display of a variable by using filters.
- Syntax: {% raw %}{{ variable | filter1:'parameter1' | filter2:'parameter2' ... }}{% endraw %}
Official documentation: https://docs.djangoproject.com/en/2.2/ref/templates/builtins/
-
Common filters:
-
Demonstration:
http://127.0.0.1:8000/test_html_param
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('test_html', views.test_html)
]
# mysite1/mysite1/views.py
def test_html_param(request):
dic = {}
dic['int'] = 88
dic['script'] = '<script>alert(1111)</script>'
return render(request, 'test_html_param.html', dic)
def say_hi():
return 'hahaha'
class Dog:
def say(self):
return 'wangwang'
# mysite1/templates/test_html_param.html
<h3>int is {{ int|add:"2" }}</h3>
<h3>str is {{ str|upper }}</h3>
<h3>script is {{ script|safe }}</h3>
Inheritance#
Template Inheritance
As shown in the example:
-
Template inheritance allows the reuse of content from the parent template, and the child template directly inherits all content from the parent template and can override the corresponding blocks in the parent template.
-
Syntax - In the parent template:
- Define block tags in the parent template
- Indicate which parts can be modified in the child template
- block tag: defined in the parent template, can be overridden in the child template
-
Syntax - In the child template:
-
Inherit template using
extends
tag (written on the first line of the template file)For example
{% extends 'base.html' %}
-
Child template rewrites the content block in the parent template
{% block block_name %} Child template block used to override the content of block_name in the parent template {% endblock block_name %} - block_name can be written or not
-
-
Overriding rules
- If not overridden, it will display according to the effect in the parent template.
- If overridden, it will display according to the overriding effect.
-
Note
- When inheriting templates, dynamic content from the server side cannot be inherited.
-
Demonstration:
http://127.0.0.1:8000/base_index
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('base_index', views.base_view, name='base_index'),
path('music_index', views.music_view),
path('sport_index', views.sport_view),
]
# mysite1/mysite1/views.py
def base_view(request):
lst = ['Tom', 'Jack']
return render(request, 'base.html', locals())
def music_view(request):
return render(request, 'music.html')
def sport_view(request):
return render(request, 'sport.html')
#-------------------------------------------------------------
# mysite1/templates/base.html # Parent template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% block mytitle %}
<title>Home</title> # Place that can be modified by child template
{% endblock %}
</head>
<body>
{{ lst }} # Child template cannot inherit variables (dynamic content)
<a href="/music_index">Music Channel</a> # Child template cannot modify
<a href="/sport_index">Sports Channel</a>
<br>
{% block info %}
This is the homepage # Place that can be modified by child template
{% endblock %}
<br>
<h3>Contact xxxx for any questions</h3> # Child template cannot modify
# mysite1/templates/music.html # Child template
{% extends 'base.html' } # Inherit parent template
{% block mytitle %}
<title>Music Channel</title> # Child template rewrites block
{% endblock %}
{% block info %}
Welcome to the Music Channel
{% endblock %}
# mysite1/templates/sport.html
{% extends 'base.html' %}
{% block mytitle %}
<title>Sports Channel</title>
{% endblock %}
{% block info %}
Welcome to the Sports Channel
{% endblock %}
Summary#
-
Filters
{
variable
|filter
1:'parameter_value
1' | filter2:'parameter_value2' ... } -
Template Inheritance
Parent template -
define modifiable blocks
Child template - inherit
parent template
; modifyblocks
defined inparent template
as needed.
3. URL Reverse Resolution#
-
Where URLs appear in the code
-
==Template== 【in HTML】
-
<a ==href==='url'>Hyperlink</a>
Clicking will redirect the page to the URL.
-
<form ==action==='url' method='post'>
Data in the form will be submitted to the URL using the post method.
-
-
In the ==view function== - 302 redirect HttpResponseRedirect('url')
Redirects the address in the user's address bar to the URL.
-
-
URL writing specifications in the code
-
==Absolute address==
-
==Relative address==
- '==/==page/1' - =='/' prefixed relative address==, the browser will add the protocol, IP, and port from the current address bar to this address as the final access address, that is, if the current page address bar is http://127.0.0.1:8000/page/3; the current relative address will ultimately result in ==
http://127.0.0.1:8000
== + /page/1 (☆ High frequency usage) - 'page/1' - ==Relative address without '/' prefix==, the browser will append this relative address to the content before the last '/' of the
current URL
as the final access address. For example, if the current address bar is ==http://127.0.0.1:8000/topic/==detail; then the final result of this relative address will be ==http://127.0.0.1:8000/topic/
== + page/1
- '==/==page/1' - =='/' prefixed relative address==, the browser will add the protocol, IP, and port from the current address bar to this address as the final access address, that is, if the current page address bar is http://127.0.0.1:8000/page/3; the current relative address will ultimately result in ==
-
-
Demonstration:
http://127.0.0.1:8000/test/url
# mysite1/mysite1/urls.py
urlpatterns = [
...
# http://127.0.0.1:8000/test/url
path('test/url', views.test_url),
path('test_url_result', views.test_url_result)
]
# mysite1/mysite1/views.py
def test_url(request):
return render(request, 'test_url.html')
def test_url_result(request):
return HttpResponse('---test url res is ok')
# mysite1/templates/test_url.html
<a href="http://127.0.0.1:8000/test_url_result">Absolute address</a>
<a href="/test_url_result">Relative address with '/'</a>
<a href="test_url_result">Relative address without '/'</a> # Browser resolves to http://127.0.0.1:8000/test/test_url_result
-
URL Reverse Resolution
-
URL reverse resolution refers to dynamically finding or calculating the corresponding route using the ==name defined in the path== in the view or template.
-
Syntax of the path function
- path(route, views, ==name==="alias")
- path('page', views.page_view, name="page_url")
- The unique name determined by the 'name=' keyword in the path can be used to reverse infer this URL information in the template or view.
-
In the ==template== - Reverse resolution of the address is achieved through the URL tag.
{% url 'alias' %} {% url 'alias' 'parameter1' 'parameter2' %} ex: {% url 'pagen' '400' %} --- All parameters are strings {% url 'person' age='18' name='gxn' %}
- Demonstration: Using in the template
http://127.0.0.1:8000/test/url
# mysite1/mysite1/urls.py urlpatterns = [ ... # http://127.0.0.1:8000/test/url path('test/url', views.test_url), path('test_urls_result/<int:age>', views.test_url_result, name='tr') # Alias tr ] # mysite1/mysite1/views.py def test_url(request): return render(request, 'test_url.html') def test_urls_result(request): return HttpResponse('---test url res is ok') # mysite1/templates/test_url.html <a href="{% url 'tr' '100' %}">URL reverse resolution version</a> # ☆ Using alias in the template
-
In the ==view function== → You can call the ==reverse== method in Django for reverse resolution.
from django.urls import reverse reverse('alias', args=[], kwargs={}) ex: print(reverse('pagen', args=[300])) print(reverse('person', kwargs= {'name':'peng', 'age':23}))
-
Demonstration:
http://127.0.0.1:8000/test/url # 302 redirect - the location tag in the response header indicates the redirect address
# mysite1/mysite1/urls.py urlpatterns = [ ... path('base_index', views.base_view, name='base_index'), # Alias base_index # http://127.0.0.1:8000/test/url path('test/url', views.test_url), path('test_urls_result/<int:age>', views.test_url_result, name='tr') # Alias tr ] # mysite1/mysite1/views.py def base_view(request): lst = ['Tom', 'Jack'] return render(request, 'base.html', locals()) def test_url(request): return render(request, 'test_url.html') def test_url_result(request, age): # 302 redirect from django.urls import reverse url = reverse('base_index') # ☆ Using alias in the view function return HttpResponseRedirect(url) #--------------------------------------------------------------- # mysite1/templates/test_url.html <a href="{% url 'tr' '100' %}">URL reverse resolution version</a> # mysite1/templates/base.html Omitted
-
-
4. Summary#
- Request (request) and Response (HttpResponse)
- GET/POST handling - request.GET/POST
- MVC and MTV
- Basic configuration of the template layer
- Template variables/tags/filters/inheritance
- URL reverse resolution