文章目录
一、Django使用自带模板
1.1 基本使用
<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>
<!-- html中列表取值用 list.index 的形式,不能用 list[index] -->
女朋友是:{{ 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>
1.1.1 模板配置
在工程中创建模板目录template,在settings.py配置文件中修改TEMPLATES配置项的DIRS值:
1.1.2 定义模板
在template目录中新建一个模板文件,如index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
Hello,{{ username }} !
{% for book in books %}
<li>{{ book.name }}</li>
{% endfor %}
</ul>
</body>
</html>
1.1.3 模板渲染
- 不使用Django框架时,模板调用(渲染)分为两步:
①找到模板:loader.get_template(模板文件在模板目录中的相对路径),返回模板对象
②渲染模板:模板对象.render(context=None, request=None),返回渲染后的html文本字符串context为模板变量字典,默认值为None。request为请求对象,默认值为None。 - Django框架提供了一个函数 render 可以简化上述流程为一步:
render(request, ‘index.html’, context)
其中request为request对象,'index.html’为模板文件路径,context为数据字典
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)
1.1.4 模板语法
1.1.4.1 模板变量 {{ var_name }}
变量名必须有字母、数字、下划线(不能以下划线开头)和点组成,语法如下:{{ 变量名 }}
模板变量可以使用python的内建类型(字符串、数字等),也可以是对象(字典、列表、元组等)。
1.1.4.2 列表取值
- html中列表取值用 {{ list.index }} 的形式,不能用 {{ list[index] }}
如:friends.2
1.1.4.3 字典取值
- html中字典取单个值要用 {{ dict.name }}的形式
如,salary.2019 - html中字典取所有值,for 循环 {% for key, value in dict**.items** %} ,注意字典变量后面一定要加 .items
1.2 流程控制 {% primary_key %}
1.2.1 for循环
<!-- {{ forloop.counter }} 可以取出迭代对象的序号 -->
{% for friend in friends %}
<li>{{ forloop.counter }} {{friend }}</li>
{% empty %} #别表为空,或不存在时执行此逻辑
{% endfor %}
- {{ forloop.counter }} 可以取出迭代对象的序号,如列表,字典,完整的forloop包括
{‘parentloop’: {}, ‘counter0’: 0, ‘counter’: 1, ‘revcounter’: 3, ‘revcounter0’: 2, ‘first’: True, ‘last’: False} tom
{‘parentloop’: {}, ‘counter0’: 1, 'counter’: 2, ‘revcounter’: 2, ‘revcounter0’: 1, ‘first’: False, ‘last’: False} jack
{‘parentloop’: {}, ‘counter0’: 2, ‘counter’: 3, ‘revcounter’: 1, ‘revcounter0’: 0, ‘first’: False, ‘last’: True} rose
1.2.2 if判断
比较运算符:==、!=、<、>、<=、>=
布尔运算符:and、or、not
注意:运算符左右两侧不能紧挨着变量或常量,必须有空格
{% if age > 10 %}
我大于10岁
{% elif %}
我不大于10岁
{% else %}
我不知道几岁
{% endif %}
1.2.3 注释
1.2.3.1 单行注释
- {# 注释:循环字典的形式 for key ,value in dict.items #}
1.2.3.2 多行注释
{% comment%}
。。。
{% endcommnet%}
1.3 过滤器(本质为函数)
1.3.1 语法:变量|过滤器:“参数”
使用管道符号|来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中。
如果过滤器需要参数,则使用冒号:传递参数
1.3.2 常用过滤器
1.3.2.1 safe,禁用转义,告诉模板这个变量是安全的,可以解释执行
1.3.2.2 length,长度,返回字符串包含字符的个数,或列表元组字典的元素个数。
1.3.2.3 default,默认值,如果变量不存在时则返回默认值。 如datal|default:‘默认值’
1.3.2.4 date,日期,用于对日期类型的值进行字符串格式化常用的格式化字符如下:
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” }}
注意:过滤器中间不能有空格
1.4 模板继承
模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。
1.4.1 父模板
如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。
标签 block:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。为了更好的可读性建议给 endblock标签写上名字,这个名字与对应的 block名字相同,父模板中也可以使用上下文中传递过来的数据。
1.4.2 子模板
标签 extends:继承,写在子模板文件的第一行
{% block名称 %}
预留区域,可以编写默认内容,也可以没有默认内容
{% endblock名称 %}
子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值
{% extends “父模板路径” %}
二、Django使用jinjia2模板
2.0 官方文档
https://jinja.palletsprojects.com/en/3.0.x/
2.1 jinjia2介绍
Jinja2是 Python下一个被广泛应用的模板引擎,是由 Python实现的模板语言,他的设计思想来源于 Django的模板引擎,并扩展了其语法和一系列强大的功能,尤其是 Flask框架内置的模板语言。
由于django默认模板引擎功能不齐全速度慢,所以我们也可以在 Django中使用jinja2,jinja2宣称比django默认模板引擎快10-20倍。
Django主流的第三方APP基本上也都同时支持Django默认模板及jinjia2,所以要用jinja2也不会有多少障碍。
2.2 安装jinjia2
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jinja2
2.3 Django配置jinjia2
2.3.1 配置
官方文档: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 默认环境配置,可加可不加
2.3.2 处理报错
ERRORS:
?: (admin.E403) A ‘django.template.backends.django.DjangoTemplates’ instance must be configured in TEMPLATES in order to use the admin application.
修改方法:两个模板引擎都打开,jinja2在上面
2.4 jinja2模板使用
2.4.1 使用jinja2
jinja2模板以函数的形式调用:{{ function(request) }}
2.4.1.1 book应用下创建jinja2_env.py
2.4.1.2 重写jinja2环境jinja2_env.py
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
2.4.1.3 修改settings.py的jinja2环境
'environment': 'book.jinja2_env.environment', # 自己重写的jinja2 环境配置,必须加
2.4.1.4 修改html中的所有过滤器,同时添加环境变量
2.4.1.5 修改pycharm的默认模板为jinja2
2.4.2 jinja2自定义过滤器
2.4.3 Django与jinja2 html文件对比
2.4.3.1 Django的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</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>
<!-- html中列表取值用 list.index 的形式,不能用 list[index] -->
女朋友是:{{ 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>
2.4.3.2 jinja2的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</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>
<!-- Django是forloop, jinja2是loop -->
<!-- {# {{ loop.index }} 可以取出迭代对象的序号 #} -->
{% for friend in friends %}
<li>{{ loop.index }} {{friend }}</li>
{% endfor %}
</ul>
<!-- 我共有 {{ friends | length }} 个朋友 <br> -->
我共有 {{ length(friends) }} 个朋友 <br>
<!-- html中列表取值用 list.index 的形式,不能用 list[index] -->
女朋友是:{{ friends.2 }} <br> 工资是:{{ salary }}
<ul>
<!-- {# 注释:django 循环字典的形式 for key ,value in dict.items #} -->
{# {% for year, money in salary.items %} #}
<li> {# {{ loop.index }}:{{ year }} : {{ money }} #}</li>
{# {% endfor %} #}
<!-- jinja2字典取值是dict[key],和Python完全一样 -->
{% for year in salary %}
<li> {{ loop.index }}:{{ year }} : {{ salary[year] }} </li>
{% endfor %}
<li> 2021年工资是:{{ salary['2021'] }}</li>
</ul>
<!-- {# jinja2 没有多行注释,只有单行注释 #} -->
<hr>
<!-- {# 我的简介是 {{ desc | safe }} #} -->
我的简介是 {{ safe(desc) }}
<hr>
</body>
</html>
三、CSRF
3.1 CSRF介绍
- CSRF全拼为 Cross Site Request Forgery译为跨站请求伪造。
- CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求。包括:以你名义发送邮件,发消息,盗取你的账号,至于购买商品虚拟货币转账等。
- 造成的问题:个人隐私泄露以及财产安全。
3.2 原理:
CSRF攻击示意图:客户端访问服务器时没有同时同服务器 做安全验证
3.3 如何防范
3.3.1 短信验证码
手机普及之后,2005年以后
3.3.2 随机码放在cookie中
3.4 CSRF小结