Django模板

本文详细介绍了Django模板的使用,从模板文件的配置和搜索顺序,到DTL模板语言的变量、标签、过滤器和注释,以及模板继承、HTML转义、CSRF保护、验证码和URL反向解析等关键概念。通过了解这些,开发者可以更高效地创建动态网页并增强应用安全性。
摘要由CSDN通过智能技术生成

Django模板的功能:产生html,控制页面上展示的内容

1. 模板文件

1.1 模板文件使用

Django中的模板文件不仅仅是一个html文件,包括两部分内容:

  • 静态内容:css, js, html
  • 动态内容:动态产生一些网页内容,通过DTL模板语言实现
使用模板文件分为以下三步:
    1. 加载模板文件(获取模板文件) ----> 返回一个模板对象
    2. 定义模板上下文(替换模板文件内的变量即向模板传递数据)
    3. 渲染模板文件 ----> 替换模板变量,生成标准的HTML页面
    4. 返回HttpResponse对象
    
示例1:django1.8.2适用
from django.template import loader, RequestContext
from django.http import HttpResponse


# 视图函数(URL处理函数)
def index(request):
    # 1. 加载模板文件
    template = loader.get_template('book/index.html')

    # 2. 定义模板上下文(给模板文件传递数据)
    context = RequestContext(request, {})
    
    # 3. 模板渲染:产生标准的HTML美容
    res_html = template.render(context, request)
    
    # 4. 返回页面给浏览器
    return HttpResponse(res_html)
    
示例2:django2.2适用
from django.template import loader
from django.http import HttpResponse


# 视图函数(URL处理函数)
def index(request):
    # 1. 加载模板文件
    template = loader.get_template('book/index.html')

    # 2. 定义模板上下文(给模板文件传递数据)
    context = {}

    # 3. 模板渲染:产生标准的HTML内容
    res_html = template.render(context, request)
    
    # 4. 返回页面给浏览器
    return HttpResponse(res_html)

注意:

  1. 模板文件配置在项目配置文件TEMPLATES项内部
  2. 快捷函数render(request, ‘模板文件’, context)实现模板内容的快速使用
1.2 模板文件搜索顺序

image

  • 首先去配置的模板目录下面去找模板文件(项目目录下templates目录)
  • 然后去INSTALLED_APPS下面的每个应用的templates去找模板文件

2. 模板语言

Django使用称为DTL的模板语言,主要包括四种类型:

  • 变量
  • 标签
  • 过滤器
  • 注释
2.1 变量

模板变量的变量名必须由字母、数字、下划线(不能以下划线开头)和点组成,语法如下:

{{ 变量 }}
字典查询,属性查询和列表索引查找都是通过一个点符号来实现
book.btitle格式:
    - 先将book当做一个字典,btitle当做键取值
    - 将book当做一个对象,先查找属性btitle,再查找方法btitle()(先属性后方法)
    - 将book当做一个列表,btitle(数字时)当做索引取值
    
解析失败,产生内容时使用空字符串填充模板变量
2.2 模板标签

模板标签需要写结束标签

代码段:{% 代码段 %}

for标签:
    {% for item in 列表 %}
        循环逻辑
    {{ forloop.counter }}表示当前是第几次循环,从1开始
    {% empty %}
    列表为空或不存在时执行此逻辑
    
    {% endfor %}
    
if标签:
    {% if ... %}
        逻辑1
    {% elif ... %}
        逻辑2
    {% else %}
        逻辑3
    {%endif%}

比较运算符:< > <= >= == != (运算符左右两侧不能紧挨变量或常量,必须有空格)
逻辑运算符:and or not

单行注释:{# 注释内容 #}
多行注释:{% comment %} {% endcomment %}

模板继承:{% extends '父模板路径' %}
模板内预留块:{% block 块名 %} {% endblock 块名 %}

加载过滤器模块:{% load 模块名 %}
2.3 过滤器

过滤器用于对模板变量进行操作

过滤器语法:模板变量|过滤器:参数

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

length :返回字符串包含字符的个数或列表、元组、字典的元素个数 {{ 变量|length }}
default: 默认值 如果变量不存在或者计算结果为False时则返回默认值 {{ 变量|default:"参数" }}
date:日期格式化  {{ 变量|date:"参数" }}

完整内容参考:http://doc.codingdict.com/django/ref/templates/builtins.html

自定义过滤器

自定义过滤器其实就是一个python函数,使用步骤如下:

注意:自定义过滤器函数至少有一个参数(前面的模板变量),最多有两个参数

1. 在应用目录下创建一个名为templatetags的python包,内部创建filters.py用于存放自定义过滤器函数
2. filters.py内部引入Library模块,创建Library对象,编写过滤器函数并使用装饰器进行注册
    from django.template import Library

    # 创建Library的对象
    register = Library()
    
    # 自定义过滤器并注册
    @register.filter
    def mod(num):
        """判断是否为偶数"""
        return num%2 == 0
    
    # 两个参数的过滤器函数
    @register.filter
    def mod2(value, num):
        """判断是否为偶数"""
        return value%num
3. 模块文档使用:加载过滤器函数,在模板变量处使用过滤器
<!DOCTYPE html>
<html lang="en">
{% load filters %}  {#加载自定义过滤器所在的模块#}
<head>
    <meta charset="UTF-8">
    <title>自定义过滤器</title>
    <style>
        .red {
            background-color: red;
        }
        .yellow {
            background-color: yellow;
        }
    </style>
</head>
<body>
    <p>图书信息:</p>
    <ul>
        {% for book in books %}
            {% if book.id|mod %}
            {# {% if book.id|mod2:3 %} 自定义过滤器函数传参 #}
                <li class="yellow">{{ book.btitle }}</li>
            {% else %}
                <li class="red">{{ book.btitle }}</li>
            {% endif %}
        {% endfor %}
    </ul>
</body>
</html>
2.4 模板继承

模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量

典型应用:网站的头部、尾部信息

继承格式:{% extends 父模板文件路径 %}  (写在子模板文件的第一行)

- 父模板与子模板不一致的地方,应在父模板内预留块,语法如下:
    {% block 块名 %}
        块中间可以写内容,也可以不写
    {% endblock 块名%}
- 子模板去继承父模板之后,可以重写父模板中的某一块的内容
    {% block 块名 %}
    {{ block.super}} #获取父模板中块的默认内容
        重写的内容
    {% endblock 块名%}

请输入图片描述

2.5 html转义
1. 模板对上下文传递的字符串进行输出时,默认会对以下字符自动转义:
    - 小于号< 转换为&lt;
    - 大于号> 转换为&gt;
    - 单引号' 转换为&#39;
    - 双引号" 转换为 &quot;
    - 与符号& 转换为 &amp;
2. 要关闭模板上下文字符串的转义:
    - {{ 模板变量|safe }}  (safe过滤器:让一个变量禁止转义)
    - {% autoescape off %}  (设置一段代码都禁用转义,接受on、off参数)
	    模板语言代码
      {% endautoescape %}
3. 模板硬编码中的字符串默认不会经过转义,如果需要转义,那需要手动进行转义
    模板硬编码不转义:{{ data|default:'<b>hello</b>' }}

3. CSRF攻击

CSRF:Cross Site Request Forgery,译为跨站请求伪造。

CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…造成的问题包括:个人隐私泄露以及财产安全。

注意:网站开发时,一些页面需要登陆之后才能访问,我们需要进行登录判断(未登录跳转到登录页)

解决方法1:使用request.session.has_key()判断用户登录状态(多个页面都写不适用)

解决方法2:登录状态监测装饰器
def login_require(view_func):
    def inner(request, *args, **kwargs):
        if request.session.has_key('isLogin'):
            return view_func(request, *args, **kwargs)
        else:
            return redirect('/books/login/')
    return inner


CSRF伪造:跨站请求伪造
1. 登录正常网站后,浏览器保存了会话的sessionid,并且没有退出
2. 意外访问另一个网站,并且该网站返回了一个有可点击按钮或者图片等的页面,并且你进行了点击
    - 关键点:伪造了向之前访问的网站发送请求(浏览器自己带着sessionid过去)
    
CSRF防护:
    - Django默认打开csrf防护中间件
    - 表单post提交添加csrf标记:使用csrf标签 ---> {% csrf_token %}
    - 注意:csrf防护只针对post提交,因此重要数据建议使用post方式提交

防护原理:
    - 渲染模板文件时在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域
    - 服务器交给浏览器保存一个名字为csrftoken的cookie信息
    - 提交表单时,两个值都会发给服务器,服务器进行比对,如果一样,则csrf验证通过,否则失败

image

4. 验证码

在用户注册、登录页面,为了防止暴力请求,可以加入验证码功能,如果验证码错误,则不需要继续处理,可以减轻业务服务器、数据库服务器的压力。

# 生成验证码的视图函数:
from PIL import Image, ImageDraw, ImageFont
from django.utils.six import BytesIO
import random

def verify_code(request):
    # 定义变量,用于画面的背景色、宽、高
    bgcolor = (random.randrange(20, 100), random.randrange(20, 100), 255)
    width = 100
    height = 25
    
    # 创建图片画布
    im = Image.new('RGB', (width, height), bgcolor)
    
    # 创建画笔对象
    draw = ImageDraw.Draw(im)
    
    # 调用画笔的point()函数绘制噪点(增加识别难度)
    for i in range(0, 100):
        xy = (random.randrange(0, width), random.randrange(0, height))  # 噪点坐标
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))  # 噪点颜色
        draw.point(xy, fill=fill)

    # 定义验证码的备选值
    str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0'
    
    # 随机选取4个值作为验证码
    rand_str = ''
    for i in range(0, 4):
        rand_str += str1[random.randrange(0, len(str1))]
        
    # 构造字体对象,ubuntu的字体路径为“/usr/share/fonts/truetype/freefont”
    font = ImageFont.truetype('FreeMono.ttf', 23)
    
    # 构造字体颜色
    fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
    
    # 绘制4个字
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
    # 释放画笔
    del draw
    
    # 存入session,用于做进一步验证
    request.session['verifycode'] = rand_str
    
    # 内存文件操作(创建BytesIO对象)
    buf = BytesIO()
    
    # 将图片保存在内存中,文件类型为png
    im.save(buf, 'png')

    # 将内存中的图片数据返回给客户端,MIME类型为图片png
    return HttpResponse(buf.getvalue(), 'image/png')
    
# 添加URL配置用于生成验证码(url(r"^/books/verify_code/", views.verify_code))
# 模板文件使用时添加img标签,src属性的URL地址请求/books/verify_code/即可生成验证码图片(同时往session_data里面写入生成的验证码内容)
# 登录验证时,先验证验证码,验证码不对直接刷新登录页面;正确再进行后续操作

5. URL反向解析

随着功能的增加会出现更多的视图,可能之前配置的url正则不够准确,于是要修改正则表达式,但是正则表达式一旦修改,之前所有对应的超链接都要修改,这很麻烦而且可能还会漏掉一些超链接忘记修改,有办法让链接根据正则表达式动态生成吗? 答:反向解析。

反向解析的作用:根据url正则表达式的配置动态的生成url

因此当某一个url配置的地址发生变化时,页面上使用反向解析的地方不需要变化(根据url正则表达式的配置动态的生成url)

反向解析使用:
1. 在项目URL配置文件包含具体应用的url配置文件时指定其url的命名空间(include函数的第二个参数)
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'books/', include('books.urls', namespace='books')),
]
2. 在应用的URL配置文件编写url配置时指定url配置的name属性(url函数的第三个参数)
urlpatterns = [
    url(r'^index/$', views.index, name='index'),  # 首页
    url(r'^temp_var/$', views.temp_var, name='temp_var'),  # 模板变量
    url(r'^temp_tags/$', views.temp_tags, name='temp_tags'),  # 模板标签
]

url反向解析用在两个地方:模板文件中的跳转链接、视图函数重定向的url链接地址
1. 模板文件中的跳转链接
使用格式:{% url 'namespace:urlname属性' %}

URL传参:
    - 位置参数:{% url 'namespace:urlname属性' 参数1 参数2 %}
    - 关键字参数:{% url 'namespace:urlname属性' id=1 age=18 %}
    
2. 视图函数重定向使用
使用格式:
    from django.core.urlresolvers import reverse
    redirect(reverse('namespace:name属性'))
URL传参:
    - 位置参数:reverse('namespace:name属性', args=位置参数元组)
    - 关键字参数:reverse('namespace:name属性', kwargs={参数})
根据提供的引用内容,我无法找到关于Django运费模板的具体信息。但是,我可以为您提供一些关于Django模板的基本知识。 Django模板是一种用于生成动态网页的工具。它允许您将静态HTML与动态数据结合在一起,以便在网页上显示动态内容。在Django中,您可以使用模板来呈现数据,并将其与视图函数中的逻辑进行分离。 在Django中,您可以创建一个模板文件,其中包含HTML和模板语言。模板语言允许您在模板中插入动态数据、循环和条件语句等。您可以使用模板标签和过滤器来处理数据并进行逻辑操作。 要使用Django模板,您需要在视图函数中加载模板,并将数据传递给模板进行渲染。然后,您可以将渲染后的模板发送给客户端以显示在浏览器中。 以下是一个简单的示例,演示如何在Django中使用模板: 1. 创建一个模板文件(例如template.html),其中包含HTML和模板语言: ```html <!DOCTYPE html> <html> <head> <title>My Django Template</title> </head> <body> <h1>Welcome to {{ website_name }}</h1> <p>Today's date is {{ current_date }}</p> </body> </html> ``` 2. 在视图函数中加载模板并将数据传递给模板进行渲染: ```python from django.shortcuts import render from datetime import date def my_view(request): website_name = "My Website" current_date = date.today() return render(request, 'template.html', {'website_name': website_name, 'current_date': current_date}) ``` 3. 在urls.py中配置URL与视图函数的映射关系: ```python from django.urls import path from .views import my_view urlpatterns = [ path('my-view/', my_view, name='my-view'), ] ``` 通过访问`http://localhost:8000/my-view/`,您将看到渲染后的模板页面,其中包含动态数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值