Django3.2模版引擎
DTL模版配置
TEMPLATES = [
{
# 配置模版引擎,默认使用Django Template Language(DTL).
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 配置全局模版(优先于应用模版),需要在项目根目录下创建一个用于存放全局模版文件的templates目录.
'DIRS': [os.path.join(BASE_DIR, 'templates')],
# 配置应用模版,为True时会自动去已配置安装的各应用包下的templates目录下搜索模版文件.
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
DTL模版渲染
$.快捷函数
【渲染函数】render函数并不是真的渲染,渲染是浏览器完成的。render函数本质上就是将html模版的内容作为一个大字符串读取出来进行处理(填充context变量、格式化模版语法等),最后将处理完的html字符串包装为HttpReqponse实例并返回。
# 快捷渲染函数render => from django.shortcuts import render
render(
request,
template_name: str, # 模版名,如'index.html'
context: dict=None, # 模版上下文,字典中的key将在模版中为全局变量
content_type=None, # MIME类型,不指定时默认为text/html; charset=utf-8
status=None, # 状态码,不指定时默认为200
using=None # 加载模板时使用的模板引擎的名称
) -> HttpResponse
【重定向函数】redirect函数内部先通过resolve_url()函数对传入的路由名进行反向解析,然后进行永久性判断(permanent是否为True),永久性跳转构造并返回HttpResponsePermanentRedirect实例,否则构造并返回HttpResponseRedirect实例。
redirect(to, *args, permanent=False, **kwargs) -> Union[HttpResponsePermanentRedirect, HttpResponseRedirect]
$.模版语法
【插值语法】DTL中的插值语法不支持单表达式,简单运算应使用过滤器。
{{ 变量名 }} {# 注意: 调用某个对象的方法时,不要加小括号,否则会报错 #}
[注意] 若插值语法中的上下文变量通过属性访问运算符读取属性时,存在差异,用{{ foo.bar }}举例,检索顺序如下
(1) 字典检索. DTL引擎会先将foo作为字典,将bar作为字典的key进行检索,即foo["bar"]
(2) 成员检索. DTL引擎按字典检索失败后,会将foo作为对象,将bar作为属性或方法进行检索,即foo.bar
(3) 索引检索. DTL引擎按成员检索也失败后,会将foo当作序列(将bar作为数字索引进),若仍失败则用空串作为结果
【流程控制】DTL中提供了多个用于进行条件渲染和列表渲染的内置标签
{# 模版标签: if语句 => 条件也支持and、or、not #}
{% if condition %} ... {% elif condition %} ... {% else %} ... {% endif %}
{# 模版标签: for循环 => 循环中还提供了一个循环变量forloop,其属性如下 #}
{# forloop参考: https://docs.djangoproject.com/en/3.2/ref/templates/builtins/ #}
{% for i in iterable %} ... {% endfor %}
【插值过滤】DTL中提供了过滤器来实现插值语法中的简单运算,内置过滤器参考。
{{ 变量|过滤器名 }} {# 单参过滤器本质上就是单参函数,管道符前面的值会被作为首参 #}
{{ 变量|过滤器名:"args" }} {# 多参过滤器本质上就是多参函数,管道符前面的值会被作为首参 #}
【模版继承】DTL提供了模版继承和模版导入的相关内置标签,用来实现模版的模块化。
{# base.html (父模版) #}
{% block 块名 %} 块内容,可省略 {% endblock %}
{# index.html (子模版) #}
{% extends 'base.html' %}
{% block 块名 %} 当前块会替换父模版中的同名块 {% endblock %}
{% include 'xxx.html' %} {# 导入模版,渲染时自动被替换为模版内容(代码替换) #}
DTL模版相关
$.安全认证
CSRF安全认证:激活CsrfViewMiddleware
中间件,在模版中的表单元素中添加用于CSRF表单验证的csrf_token组件。
{% csrf_token %} {# 将该组件置于form表单中,进行跨站请求伪造保护,防止跨站攻击 #}
[验证原理] 渲染函数会在处理模版时将{%csrf_token%}会被转化为一个名为scrfmiddlewaretoken的隐藏表单控件(即<input type="hidden" name="scrfmiddlewaretoken" value="token值" />
)。当激活CsrfViewMiddleware
中间件后,客户端首次访问站点时,该中间件会在客户端的Cookie中设置上token值,之后当客户端进行表单提交时,浏览器就会自动将控件中的token值和Cookie中的scrf_token值一并携带到后端,然后CSRF中间件将二者取出并进行比较,相同则认证通过,否则触发403,本质上也是双Cookie验证。
* 身份验证
Django的验证系统除了login、logout、authenticate方法外,还提供了@login_required和LoginRequireMixin做登陆判断,此二者本质上都是根据request.user的is_authenticated属性对登陆状态进行判断,使用方式如下
# 用于视图函数的登陆判断方式,认证失败自动重定向.
@login_required(login_url='/login/')
def my_view(request):
pass
# 用于视图类的登陆判断方式,认证失败自动重定向.
class MyView(LoginRequiredMixin, View):
login_url = '/login/'
$.页面缓存
🔗 缓存整个站点:https://docs.djangoproject.com/zh-hans/3.2/topics/cache/#the-per-site-cache
🔗 缓存模版片段:https://docs.djangoproject.com/zh-hans/3.2/topics/cache/#template-fragment-caching