<ul>
{% for book in books %}
<li>{{ book.name }}li>
{% endfor %}
ul>
Hello,{{ username }} !
<hr>
我没有定义的变量:{{ no_defined | default:"我是默认值" }}
<hr>
我的年龄是:{{ age }} <br>
{% if age > 10 %}
我大于10岁
{% else %}
我不大于10岁
{% endif %} <br>
出生日期是:{{ birthday | date:"Y-m-d H:i:s" }} <br>
朋友有:
<ul>
{ forloop.counter }} 可以取出迭代对象的序号 -->
{% for friend in friends %}
<li>{{ forloop.counter }} {{friend }}li>
{% endfor %}
ul>
我共有 {{ friends | length }} 个朋友 <br>
女朋友是:{{ friends.2 }} <br>
工资是:{{ salary }}
<ul>
{# 注释:循环字典的形式 for key ,value in dict.items #}
{% for year, money in salary.items %}
<li> {{ forloop.counter }}:{{ year }} : {{ money }} li>
{% endfor %}
<li> 2021年工资是:{{ salary.2021 }}li>
ul>
{% comment %}
这里是多行注释
{% endcomment %}
<hr>
我的简介是 {{ desc | safe }}
<hr>
在工程中创建模板目录template,在settings.py配置文件中修改TEMPLATES配置项的DIRS值:

在template目录中新建一个模板文件,如index.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<ul>
Hello,{{ username }} !
{% for book in books %}
<li>{{ book.name }}li>
{% endfor %}
ul>
body>
html>
class HomeView(View):
def get(self, request):
# 1、数据库中查询数据
books = BookInfo.objects.all()
username = request.GET.get('username')
# 2、组织数据
context = {
'books': books,
'username': username
}
# 3、数据传递给模板
return render(request, 'index.html', context)
变量名必须有字母、数字、下划线(不能以下划线开头)和点组成,语法如下:{{ 变量名 }}
模板变量可以使用python的内建类型(字符串、数字等),也可以是对象(字典、列表、元组等)。



{ forloop.counter }} 可以取出迭代对象的序号 -->
{% for friend in friends %}
<li>{{ forloop.counter }} {{friend }}li>
{% empty %} #别表为空,或不存在时执行此逻辑
{% endfor %}
比较运算符:==、!=、<、>、<=、>=
布尔运算符:and、or、not
注意:运算符左右两侧不能紧挨着变量或常量,必须有空格
{% if age > 10 %}
我大于10岁
{% elif %}
我不大于10岁
{% else %}
我不知道几岁
{% endif %}

{% comment%}
。。。
{% endcommnet%}

使用管道符号|来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中。
如果过滤器需要参数,则使用冒号:传递参数




Y表示年,格式为4位,y表示两位的年
m表示月,格式为01.02.12等
d表示日,格式为01.02等
j表示日,格式为12等
H表示时,24进制,h表示12进制的时
i表示分,为0-59
s表示秒,为0-59
如{{ birthday | date:“Y-m-d H:i:s” }}
注意:过滤器中间不能有空格

模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。
如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。
标签 block:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。为了更好的可读性建议给 endblock标签写上名字,这个名字与对应的 block名字相同,父模板中也可以使用上下文中传递过来的数据。
标签 extends:继承,写在子模板文件的第一行
{% block名称 %}
预留区域,可以编写默认内容,也可以没有默认内容
{% endblock名称 %}
子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值
{% extends “父模板路径” %}

https://jinja.palletsprojects.com/en/3.0.x/
Jinja2是 Python下一个被广泛应用的模板引擎,是由 Python实现的模板语言,他的设计思想来源于 Django的模板引擎,并扩展了其语法和一系列强大的功能,尤其是 Flask框架内置的模板语言。
由于django默认模板引擎功能不齐全速度慢,所以我们也可以在 Django中使用jinja2,jinja2宣称比django默认模板引擎快10-20倍。
Django主流的第三方APP基本上也都同时支持Django默认模板及jinjia2,所以要用jinja2也不会有多少障碍。
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jinja2
官方文档:https://docs.djangoproject.com/en/3.2/topics/templates/

谷歌页面翻译

原来的:TEMPLATES = [‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,]

修改为:TEMPLATES = [‘BACKEND’: ‘django.template.backends.jinja2.Jinja2’,]

‘environment’: ‘jinja2.Environment’, # jinja2 默认环境配置,可加可不加

ERRORS:
?: (admin.E403) A ‘django.template.backends.django.DjangoTemplates’ instance must be configured in TEMPLATES in order to use the admin application.

修改方法:两个模板引擎都打开,jinja2在上面

jinja2模板以函数的形式调用:{{ function(request) }}

from jinja2 import Environment
from django.template.defaultfilters import date, default, length, safe
def environment(**options):
# 1、创建Environment 实例对象
env = Environment(**options)
# 2、指定(更新)jinja2的函数指向Django的指定过滤器
env.globals.update({
'default': default,
'date': date,
'length': length,
'safe': safe,
})
# 3、返回Environment实例
return env
'environment': 'book.jinja2_env.environment', # 自己重写的jinja2 环境配置,必须加



DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<ul>
{% for book in books %}
<li>{{ book.name }}li>
{% endfor %}
ul>
Hello,{{ username }} !
<hr>
我没有定义的变量:{{ no_defined | default:"我是默认值" }}
<hr>
我的年龄是:{{ age }} <br>
{% if age > 10 %}
我大于10岁
{% else %}
我不大于10岁
{% endif %} <br>
出生日期是:{{ birthday | date:"Y-m-d H:i:s" }} <br>
朋友有:
<ul>
{ forloop.counter }} 可以取出迭代对象的序号 -->
{% for friend in friends %}
<li>{{ forloop.counter }} {{friend }}li>
{% endfor %}
ul>
我共有 {{ friends | length }} 个朋友 <br>
女朋友是:{{ friends.2 }} <br>
工资是:{{ salary }}
<ul>
{# 注释:循环字典的形式 for key ,value in dict.items #}
{% for year, money in salary.items %}
<li> {{ forloop.counter }}:{{ year }} : {{ money }} li>
{% endfor %}
<li> 2021年工资是:{{ salary.2021 }}li>
ul>
{% comment %}
这里是多行注释
{% endcomment %}
<hr>
我的简介是 {{ desc | safe }}
<hr>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<ul>
{% for book in books %}
<li>{{ book.name }}li>
{% endfor %}
ul>
Hello,{{ username }} !
<hr>
<hr>
我的年龄是:{{ age }} <br>
{% if age > 10 %}
我大于10岁
{% else %}
我不大于10岁
{% endif %} <br>
{ no_defined | default:"我是默认值" }} #} -->
我没有定义的变量:{{ default(no_defined, "我是默认值") }}
{ birthday | date:"Y-m-d H:i:s" }} #} -->
出生日期是:{{ date(birthday, "Y-m-d H:i:s") }} <br>
朋友有:
<ul>
{ loop.index }} 可以取出迭代对象的序号 #} -->
{% for friend in friends %}
<li>{{ loop.index }} {{friend }}li>
{% endfor %}
ul>
{ friends | length }} 个朋友
-->
我共有 {{ length(friends) }} 个朋友 <br>
女朋友是:{{ friends.2 }} <br> 工资是:{{ salary }}
<ul>
{# {% for year, money in salary.items %} #}
<li> {# {{ loop.index }}:{{ year }} : {{ money }} #}li>
{# {% endfor %} #}
{% for year in salary %}
<li> {{ loop.index }}:{{ year }} : {{ salary[year] }} li>
{% endfor %}
<li> 2021年工资是:{{ salary['2021'] }}li>
ul>
<hr>
{ desc | safe }} #} -->
我的简介是 {{ safe(desc) }}
<hr>
body>
html>
CSRF攻击示意图:客户端访问服务器时没有同时同服务器 做安全验证

手机普及之后,2005年以后












