Python—Django中的模板(template)

作者:BerenCamlost

目录

  • 作者:BerenCamlost
  • 1 定义模板
    • 1.1 变量
      • 在模板中调用方法
    • 1.2 标签
      • 1.2.1 语法
      • 1.2.2 作用
      • 1.2.3 if
      • 1.2.4 for
      • 1.2.5 comment
      • 1.2.6 ifequal/ifnotequal
      • 1.2.7 include
      • 1.2.8 url
      • 1.2.9 csrf_token
      • 1.2.10 block, extends
      • 1.2.11 autoescape
    • 1.3 过滤器
      • 1.3.1 upper/lower
      • 1.3.2 过滤器可以传递参数
      • 1.3.3 default默认值
      • 1.3.4 date
      • 1.3.5 escape
      • 1.3.6 加减乘除
      • 1.3.7 给之前的学生列表加背景颜色
    • 1.4 注释
  • 2 反向解析
    • 2.1 作用
    • 2.2 示例
    • 2.3 传入参数
  • 3 模板继承
    • 3.1 作用
    • 3.2 block标签
    • 3.3 extends标签
    • 3.4 示例
  • 4 HTML转义
    • 4.1 问题
    • 4.2 解决
    • 4.3 示例
  • 5 CSRF
    • 5.1 跨站请求伪造
    • 5.2 防止CSRF
  • 6 验证码
    • 6.1 作用
    • 6.2 源码及效果
    • 6.3 输入验证码
      • 6.3.1 视图
      • 6.3.2 url
      • 6.3.3 模板

1 定义模板

1.1 变量

  • 视图传递给模板的数据
  • 要遵守标识符规则
  • 语法 { {var}}(var代表变量)
  • 【注意】:如果使用的变量不存在,则插入的是空字符串
  • 在模板中使用点语法,点后边的东西按如下顺序进行匹配
    • 字典查询
    • 属性或者方法
    • 数字索引

在模板中调用方法

  1. sunck/models.py:
# 插入到Students类中的方法
def get_name(self):
    return self.sname
  1. sunck/views.py:
# templates 测试
def templates(request):
    stu = Students.stuObj2.get(sname='刘德华')
    return render(request, 'sunck/templates测试/templates1.html', {
     'stu': stu})
  1. sunck/urls.py:
    path('template/', views.templates),
  1. sunck/templates测试/templates.html:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板测试title>
head>
<body>
<h1>{
    { stu.get_name }}h1>
<h1>{
    { stu.sname }}h1>

body>
html>
  1. 效果:
    Python—Django中的模板(template)_第1张图片
  • 【注意】:在模板中调用方法时不能传递参数

1.2 标签

1.2.1 语法

{% tag %}

1.2.2 作用

  1. 在输出中创建文本
  2. 控制逻辑和循环

1.2.3 if

  1. 格式:

{% if 表达式 %}
    语句
{% endif %}


{% if 表达式 %}
    语句1
{% else %}
    语句2
{% endif %}


{% if 表达式1 %}
    语句1
{% elif 表达式2 %}
    语句2
    ·
    ·
    ·
{% elif 表达式n %}
    语句n
{% else %}
    语句e
{% endif %}
  1. 举例

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板测试title>
head>
<body>
    <h1>{
    { stu.get_name }}h1>
    <h1>{
    { stu.sname }}h1>

    <h1>num={
    { num }}h1>
    {% if num is 10 %}
    <h2>You are a handsome boyh2>
    {% elif num is 20 %}
        <h2>you are a Very handsome boyh2>
    {% else %}
        <h2>You are not a handsome boyh2>
    {% endif %}
body>
html>

在Views.py中给num传一个数字,得到效果如下图所示:
Python—Django中的模板(template)_第2张图片

1.2.4 for

{% for 变量 in 列表 %}
{#语句1#}
{% empty %}
{#语句2#}
{% endfor %}
  • 【注意】:当列表为空或者不存在时,执行empty语句,empty可有可无
  • { { forloop.counter }}表示循环次数,可以用在for语句中,例如:
    <ul>
        {% for student in stu1 %}
        {#语句1#}
            <li>{
    { forloop.counter }}:{
    { student.sname }}---{
    { student.scontend }}li>
        {% empty %}
        {#语句2#}
            <li>没有学生信息li>
        {% endfor %}
    ul>
  • views.py文件中为:
def templates(request):
    stu1 = Students.stuObj2.all()
    # stu1 = Students.stuObj2.filter(sname__startswith="刘")
    # stu1 = Students.stuObj2.filter(sname__startswith="Liu")
    return render(request, 'sunck/templates测试/templates1.html', {
      'stu1': stu1})

1.2.5 comment

  • 格式
{% commnet %}
    被注释的内容
{% endcomment %}
  • 作用:相当于多行注释,被注释的内容不再执行

1.2.6 ifequal/ifnotequal

  • 【作用】:判断是否相等或者不相等
  • 【格式】:
{% ifequal 值1 值2 %}
    语句1
{% endifequal %}  # 如果值1等于值2,执行语句1,否则不执行语句1

1.2.7 include

  • 【作用】:加载模板并以标签内的参数渲染
  • 【格式】:{% include '模板目录' 参数1 参数2 %}

1.2.8 url

  • 【作用】:反向解析
  • 【格式】:{% url 'namespace: name' p1 p2 %}

1.2.9 csrf_token

  • 【作用】:用于跨站请求伪造保护
  • 【格式】:{% csrf_token %}

1.2.10 block, extends

  • 【作用】:用于模板的继承

1.2.11 autoescape

  • 【作用】:用于HTML转义

1.3 过滤器

  • 【语法】:{ {var|过滤器}}
  • 【作用】:在变量被显示前修改它,只是加一个效果,对变量不会造成影响

1.3.1 upper/lower

  • 大写和小写,示例:
{#5. 过滤器#}
<h1>原型:{
    { str }}h1>
<h1>upper:{
    { str|upper }}h1>
<h1>lower:{
    { str|lower}}h1>
  • 【效果】:
    Python—Django中的模板(template)_第3张图片

1.3.2 过滤器可以传递参数

  • 下面以var|join:'str'为例解释传参的过程:
# templates 测试
def templates(request):
    stu1 = Students.stuObj2.all()
    return render(request, 'sunck/templates测试/templates1.html', {
     'stu1': stu1,})
<h2>{
    { stu1|join:"--的儿子是-->" }}h2>

【效果】(涉及隐私我打了马赛克):
效果

1.3.3 default默认值

  • 如果一个变量没有被提供,或者值为false,空,我们可以通过 default 语法使用默认值
  • 【示例】:

    { { stu1.sname|default:'啥都么的' }}

1.3.4 date

  • 【作用】:根据给定格式转换日期为字符串
  • 【示例】:{ {dateVal|date:'y-m-d'}}
    以年月日的形式显示日期,dateVal是一个日期变量

1.3.5 escape

  • 【作用】:HTML转义

1.3.6 加减乘除

  • 【示例】:
<ul>
    <li>num:{
    { num }}li>
    <li>num+10:{
    { num|add:10 }}li>
    <li>num-5:{
    { num|add:-5 }}li>
    
    <li>num*5:{% widthratio num 1 5 %}li>
    <li>num/2:{% widthratio num 2 1 %}li>
ul>
  • 效果:
    Python—Django中的模板(template)_第4张图片

1.3.7 给之前的学生列表加背景颜色

  • |divisibleby:2:可被2整除
<ul>
    {% for student in stu1 %}
        {% if forloop.counter|divisibleby:2 %}
            <li style="background-color: gray">{
    { forloop.counter }}:{
    { student.sname }}---{
    { student.scontend }}li>
        {% else %}
            <li style="color: orange">{
    { forloop.counter }}:{
    { student.sname }}---{
    { student.scontend }}li>
        {% endif %}
    {% empty %}
        <li>没有学生信息li>
    {% endfor %}
ul>
  • 【效果】(打码真的费时间):
    Python—Django中的模板(template)_第5张图片

1.4 注释

  • 【单行注释】:{ {# #}}
  • 【多行注释】:{%comment%}....{%endcomment%}

2 反向解析

2.1 作用

即使url变动,也可以根据namespace和name反向解析出正确的域名,从而实现超链接的正确执行。

2.2 示例

<a href="{% url 'sunck:good' %}">反解析连接gooda>
# project/project/urls.py
urlpatterns = [
    path('sunck/', include('sunck.urls', namespace="sunck")),
]
# project/sunck/urls.py
urlpatterns = [
    path('template/good/', views.good, name='good'),
]

2.3 传入参数

模板:

<a href="{% url 'sunck:good' 1 %}">反解析连接gooda>

url:

path('template/good/', views.good, name='good'),

views视图:

# templates-反向解析 测试
def good(request, id):
    return render(request, 'sunck/templates测试/good.html', {
     'num': id})

good模板:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>goodtitle>
head>
<body>
    <h1>good--{
    { num }}h1>
body>
html>

3 模板继承

3.1 作用

  • 模板继承可以减少页面的重复定义,实现页面的重用

3.2 block标签

  • 【作用】:在父模板中预留区域 ,子模板去填充
  • 【语法】:
{% block 标签名 %}
...
{% endblock 标签名 %}

3.3 extends标签

  • 继承模板,需要写在模板文件的第一行
  • 【语法】:
{% extends 'myApp/base.html(父模板路径)' %}
{% block 标签名 %}
内容
{% endblock 标签名 %}

3.4 示例

  • base.html:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>basetitle>
head>
<body>
    <div id="header">
        <h1>headerh1>
    div>
    <div id="main">
        {% block main %}

        {% endblock main %}
    div>
    <div id="footer">
        <h1>footerh1>
    div>

body>
html>
  • main.html:
{% extends "sunck/模板继承/base.html" %}
{% block main%}
    <h1>{
    { 'main'|upper }}h1>
{% endblock main %}

4 HTML转义

4.1 问题

# templates 测试
def templates(request):
    return render(request, 'sunck/templates测试/templates1.html',
                  {
     
                   'str2': '

HTML转义

'
})
{#6 HTML转义#}
{
    { str2 }}
  • 这时的输出为

    HTML转义

    ,未经过渲染,而我们想要的输出是

    HTML转义

4.2 解决

  • 过滤器safe可以关闭转义,escape开启转义
  • 标签{% autoescape off %}...{% endautoescape %}关闭自动转义,将off变成on开启自动转义

4.3 示例

  • html文件:
{#6 HTML转义#}
{
    { str2 }}
{
    { str2|escape }}
{
    { str2|safe }}
{% autoescape on %}
    1{
    { str2 }}
    2{
    { str2 }}
{% endautoescape %}
{% autoescape off %}
    1{
    { str2 }}
    2{
    { str2 }}
    3{
    { str2 }}
{% endautoescape %}
  • 【效果】:
    Python—Django中的模板(template)_第6张图片

5 CSRF

5.1 跨站请求伪造

某些恶意网站包含链接,表单,按钮,js,利用登录用户在浏览器中认证,从而攻击服务

5.2 防止CSRF

  1. 在settings.py文件的MIDDLEWARE增加'django.middleware.csrf.CsrfViewMiddleware'
    Python—Django中的模板(template)_第7张图片
  2. 上述方法会将所有的跨站请求屏蔽,为了允许自身的跨站请求服务,应该在HTML页面中加入{% csrf_token %},如:
<form action="../register/" method="post">
    {% csrf_token %}
    
    姓名:<input type="text" name="name" value=""/>
    <hr>
    性别:<input type="radio" name="gender" value="1"><input type="radio" name="gender" value="0"><hr>
    年龄:<input type="text" name="age" value=""/>
    <hr>
    爱好:<input type="checkbox" name="hobby" value="power"/>权利<input type="checkbox" name="hobby" value="money">金钱<input type="checkbox" name="hobby" value="beauty">美女<input type="checkbox" name="hobby" value="Tesla">Tesla
    <hr>
    <input type="submit" value="注册">
form>

6 验证码

6.1 作用

  • 在用户注册,登录页面的时候使用,为了防止暴力请求,减轻服务器的压力
  • 是防止CSRF的一种方式

6.2 源码及效果

  • 请查看作者的另外一篇博客:用Python写一个自动生成简单验证码图片的程序

6.3 输入验证码

6.3.1 视图

def verifi_code(request):
    return render(request, 'sunck/templates测试/verificationcode.html', )


# 展示结果
def show(request):
    code = request.POST.get('code')
    right_code = request.session['verification_code']
    if code.upper() == right_code.upper():
        return HttpResponse('对了!'+right_code)
    else:
        return HttpResponse('错了!'+code+'----'+right_code)

6.3.2 url

    path('VerificationCode/code', VerificationCode.verification_code),
    path('VerificationCode/', VerificationCode.verifi_code),
    path('VerificationCode/show', VerificationCode.show, name='show'),

6.3.3 模板


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>验证码title>
head>
<body>
    <h3>请输入验证码h3>
    <form method="post" action="{% url 'sunck:show' %}">
        {% csrf_token %}
        <input type="text" name="code" value=""/>
        <img src="/sunck/VerificationCode/code">
        <hr>
        <input type="submit" value="登录"/>
    form>
body>
html>

你可能感兴趣的:(Python—Django,Python,Django,模板)