脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - Python全栈之模板渲染详解

Python全栈之模板渲染详解

2022-09-27 11:09熬夜泡枸杞 Python

这篇文章主要为大家详细介绍了Python全栈之模板渲染,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

1. 标签

{% 标签 %}

1.1 for循环标签

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<ul>
<!-- 可迭代对象都可以用循环 -->
<!-- 循环列表 -->
    {% for foo in hobby %}
        <li>{{ foo }}</li>
        {% empty %}  <!-- 当循环的数据为空或者没有这个变量时显示empty下面的内容 -->
        <h1>啥也没有</h1>
    {% endfor %}
</ul>
 
<ul>
    <!-- 循环字典 -->
    {% for foo in d1 %}  <!-- 只能获取键 -->
        <li>{{ foo }}</li>
    {% endfor %}
    {% for key,value in d1.items %}  <!-- 获取键值对,items.keys,values都能用 -->
        <li>{{ key }} -- {{ value }}</li>
    {% endfor %}
 
</ul>

forloop对象

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<ul>
    {% for foo in hobby %}
        forloop  循环标签对象,通过counter属性可以来记录循环次数
        <li>{{ forloop.counter }}---{{ foo }}</li> 从1开始计数
        <li>{{ forloop.counter0 }}---{{ foo }}</li> 从0开始计数
        <li>{{ forloop.revcounter }}---{{ foo }}</li> 倒序,从1开始计数
        <li>{{ forloop.revcounter0 }}---{{ foo }}</li> 倒序,从0开始计数
        <li>{{ forloop.first }}---{{ foo }}</li> 如果是第一次循环,就得到True
        <li>{{ forloop.last }}---{{ foo }} </li>  如果是最后一次循环,就得到True,其他为False
 
    {% endfor %}
</ul>
   
    {% for key,value in hobby2.items %}
        forloop.parentloop 统计外层循环对象的循环次数
        {% for v in value %}
            <li>{{ forloop.parentloop.counter }} -- {{ forloop.counter }} -- {{ v }}</li>
        {% endfor %}
 
    {% endfor %}
    
reversed 倒序循环
 <ul>
    {% for foo in hobby reversed %}
        <li>{{ foo }} </li>
 
    {% endfor %}
</ul>

1.2 if标签

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{% if age > 18 %}
    <h1>太老了</h1>
{% elif age == 18 %}
    <h1>还行</h1>
{% else %}
    <h1>挺嫩</h1>
{% endif %}
{% if age > 18 or number > 100 %} <!-- 符号两边必须有空格 -->
    <h1>太老了</h1>
{% elif age == 18 %}
    <h1>还行</h1>
{% else %}
    <h1>挺嫩</h1>
{% endif %}
{% if hobby|length > 3 %} <!-- 可以配合过滤器来使用 -->
    <h1>爱好还挺多</h1>
{% else %}
    <h1>爱好不够多</h1>
{% endif %}

f语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。

注意:不能像下面这样写

?
1
2
3
{% if a > b > c %}
...
{% endif %}

Django的模板语言中属性的优先级大于方法

?
1
2
3
4
5
6
7
d2 = {'items': [11,22,33]}
优先使用items属性,不使用items方法,容易导致错误
<ul>
    {% for key,v in d2.items %}
        <li>{{ key }} -- {{ v }}</li>
    {% endfor %}
</ul>

1.3 with标签

给调用过程比较长的数据起别名的.

?
1
2
3
4
5
6
7
8
9
写法1.
{% with hobby2.xx.0 as kk %}
    <h1>{{ kk }}</h1>
    <h2>{{ kk }}</h2>
{% endwith %}
{% with kk=hobby2.xx.0 %}
    <h1>{{ kk }}</h1>
    <h2>{{ kk }}</h2>
{% endwith %}

1.4 csrf token标签

?
1
2
3
4
5
<form action="" method="post">
    {% csrf_token %}  <!-- 加上这个标签之后,post请求就能通过django的csrf认证机制,就不需要注释settings的配置了 -->
    <input type="text" name="uname">
    <input type="submit">
</form>

2. 模板继承

先创建一个母版(模板)

比如base.html

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        .c1{
            background-color: pink;
            height: 40px;
        }
        .left-menu{
            background-color: tan;
            width: 200px;
            min-height: 600px;
        }
        .item{
            background-color: yellow;
            height: 40px;
            border-bottom: 1px solid red;
        }
        .left{
            float: left;
        }
        .right{
            float: left;
        }
    </style>
    {% block css %}
    {% endblock %}
</head>
<body>
<div class="nav">
    <div class="c1">
        <a href="">32官网</a>
        <span>性感荷官, 在线发牌</span>
    </div>
</div>
<div class="main">
    <div class="left">
    <div class="left-menu">
        <div class="menu1 item">
            <a href="/t1/">菜单1</a<!-- 写相对路径时,前面的斜杠必须写 -->
        </div>
        <div class="menu2 item">
            <a href="/t2/">菜单2</a>
        </div>
        <div class="menu3 item">
            <a href="/t3/">菜单3</a>
        </div>
    </div>
</div>
<div class="right">
    <div class="content">
        {% block content %}
            <h1>基础模板</h1>
        {% endblock %}
    </div>
</div>
</div>
</body>
{% block js %}
{% endblock %}
</html>

在模板中预留block块(叫做 钩子)

?
1
2
3
{% block content %}
    <h1>基础模板</h1>
{% endblock %}

子页面中继承模板extends

并重写模板中预留的block块中的内容

{{ block.super }}显示模板的内容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
{% extends 'base.html' %}
{% block css %}
    <style>
        .c1{
            background-color: green;
            height: 40px;
        }
    </style>
{% endblock %}
{% block content %}
    <h1>性感美女,在线指导</h1>
    {{ block.super }} <!-- 显示模板的内容 -->
{% endblock %}

block块的写法

?
1
2
3
4
5
6
{% block content %}
...
{% endblock %}
{% block content %}
...
{% endblock content %}    可以指定endblock的名称,起到一个提示作用

3. 组件

一个完整功能的模块,其他页面如果想使用,就直接以组件的形式引入

比如创建一个zujian.htmlm,内容如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        .c1{
            background-color: pink;
            height: 40px;
        }
    </style>
</head>
<body>
 
<div class="nav">
    <div class="c1">
        <a href="">32官网</a>
        <span>性感荷官, 在线发牌</span>
    </div>
</div>
</body>
</html>

在home.html中引入一下include

在页面什么位置引入,组件效果就生成到什么位置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>这是home页面</h1>
{% include 'zujian.html' %}
 
</body>
</html>

静态文件的配置流程

1 在settings.py文件中加上如下配置

?
1
2
3
4
5
6
STATIC_URL = '/static/'  #别名,映射到STATICFILES_DIRS配置的静态文件存放路径,#那么引入静态文件时,我们使用别名路径来写,如果使用别名路径, 那么修改静态文件夹名称之后,也不会影响静态文件的返回# STATIC_URL = '/abc/'  别名可以修改的STATICFILES_DIRS = [    os.path.join(BASE_DIR, 'statics'),]STATIC_URL = '/static/'  #别名,映射到STATICFILES_DIRS配置的静态文件存放路径,
#那么引入静态文件时,我们使用别名路径来写,如果使用别名路径, 那么修改静态文件夹名称之后,也不会影响静态文件的返回
# STATIC_URL = '/abc/'  别名可以修改的
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'statics'),
]

2 在项目根目录下创建一个文件夹,名称随意,比如叫做statics

3 在html文件中引入(两种方式)

方式1

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/css/xx.css"> 方式1   直接写别名路径开头
</head>
<body>
<div class="c1">xxx</div>
 
</body>
</html>

方式2:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% load static %}   先load一下static
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="{% static 'css/xx.css' %}" > 方式2
 
</head>
<body>
<div class="c1">xxx</div>
 
</body>
</html>

4. 自定义过滤器

1 在应用文件夹中创建一个叫做templatetags的文件夹(注意,名称必须是它)

2 在templatetags文件夹中创建一个py文件,名称随意,比如叫做mytag.py

3 在mytag.py文件中写如下内容

?
1
2
3
4
5
6
7
8
from django import template
register = template.Library()  #注册器,变量名称必须叫register
@register.filter   #过滤器
def xx(v1):  #第一参数是使用过滤器时,管道符前面的数据 <h1>{{ name|xx }}</h1>
    return v1 + 'xx'
@register.filter   #过滤器,至多有两个参数
def xx2(v1, v2):  #第一参数是使用过滤器时,管道符前面的数据 ,第二个参数是冒号后面的值,<h1>{{ name|xx:'oo' }}</h1>
    return v1 + 'xx2' + v2

4 在html文件中使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% load mytag %}   先load一下我们的mytagpy文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>这是home页面</h1>
{#{% include 'zujian.html' %}#}
<h1>{{ name|xx }}</h1>   #以过滤器的形式使用,这个是一个参数的
<h1>{{ name|xx2:'oo' }}</h1> # 以过滤器的形式使用,这个是两个参数的
</body>
</html>

5. 自定义标签

1 在应用文件夹中创建一个叫做templatetags的文件夹(注意,名称必须是它)

2 在templatetags文件夹中创建一个py文件,名称随意,比如叫做mytag.py

3 在mytag.py文件中写如下内容

?
1
2
3
4
5
6
from django import template
register = template.Library()  #注册器,变量名称必须叫register
 
@register.simple_tag
def tag1(v1, v2 ,v3):  #参数个数没有限制
    return v1 + v2 + v3

4 在html文件中使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
{% load mytag %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
 
<h1>{% tag1 11 22 number %}</h1<!-- 先写标签名称,然后写参数,参数以空格分隔 ,最终得到的tag1的return值 -->
</body>
</html>

6. inclusion_tag 自定义标签

这个可以模拟不同用户,所看到的功能模块不一样,就是用这个实现的

1 在应用文件夹中创建一个叫做templatetags的文件夹(注意,名称必须是它)

2 在templatetags文件夹中创建一个py文件,名称随意,比如叫做mytag.py

3 在mytag.py文件中写如下内容

?
1
2
3
4
5
6
7
8
from django import template
register = template.Library()  #注册器,变量名称必须叫register
# 通过inclusion_tag来做为装饰器,并且需要传入一个参数,这个参数就是一个html文件(你想做成动态组件的html文件)
@register.inclusion_tag('zujian2.html')
def dongtai(v1):  #参数没有个数限制
    data = v1  #[11,22,33,44,55,66]
    return {'xx': data }
# zujian2.html会收到定义的inclusion_tag函数的返回值,然后进行zujian2.html这个动态组件的模板渲染

zujian2.html

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        .left-menu {
            background-color: tan;
            width: 200px;
            min-height: 600px;
        }
        .item {
            background-color: yellow;
            height: 40px;
            border-bottom: 1px solid red;
        }
        .left {
            float: left;
        }
    </style>
</head>
<body>
<div class="left">
        <div class="left-menu">
            {% for item in xx %}  <!-- [11,22,33] ,注意 data这是inclusion_tag函数的返回值那个字典中的键 -->
                <div class="menu1 item">
                    <a href="/t1/">{{ item }}</a<!-- 写相对路径时,前面的斜杠必须写 -->
                </div>
            {% endfor %}
        </div>
    </div>
 
</body>
</html>

4 使用inclusion_tag

basic.html

?
1
2
3
4
5
6
7
8
9
10
11
12
{% load mytag %}   先load
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
{% dongtai menu_list %#最终将渲染好的动态组件(zujian2.html),通过include引入组件的方式,加载到这里
</body>
</html>

5 在后台视图中渲染basic.html页面是可以传入动态数据

?
1
2
3
4
5
6
def basic(request):
    # if user.type == 'admin':
    # menu_list = [11,22,33,44,55,66]
    # else:
    menu_list = [22,33]
    return render(request, 'basic.html',{'menu_list': menu_list})

7. 小提示与小练习

小提示

?
1
2
3
4
5
6
自定义标签和过滤器在前后端未分离的项目用的比较多一些
前后端分离的项目用的比较少
@register.inclusion_tag('zujian2.html')
def dongtai(v1):
      data = v1
      return {'xx':data}  # 这个return 相当于render(zujian2.html,{'xx':data})

小练习

页面效果

Python全栈之模板渲染详解

Python全栈之模板渲染详解

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!    

原文链接:https://blog.csdn.net/weixin_46818279/article/details/122934173

延伸 · 阅读

精彩推荐
  • Pythonpycharm激活方法到2099年(激活流程)

    pycharm激活方法到2099年(激活流程)

    这篇文章主要介绍了pycharm激活方法到2099年,文末给大家提到了idea和pycharm最新版激活方法,非常不错对大家的学习或工作具有一定的参考借鉴价值,需要的...

    托尼stark13002020-09-16
  • PythonPython selenium 三种等待方式详解(必会)

    Python selenium 三种等待方式详解(必会)

    这篇文章主要介绍了Python selenium 三种等待方式详解(必会)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下...

    huilan_same5092020-09-07
  • Python详解Python3.6安装psutil模块和功能简介

    详解Python3.6安装psutil模块和功能简介

    这篇文章主要介绍了详解Python3.6安装psutil模块和功能简介,详细的介绍了安装psutil模块和该模块的使用,小编觉得挺不错的,现在分享给大家,也给大家做...

    在奋斗的大道5852021-02-27
  • Pythonpython通过pil模块将raw图片转换成png图片的方法

    python通过pil模块将raw图片转换成png图片的方法

    这篇文章主要介绍了python通过pil模块将raw图片转换成png图片的方法,实例分析了Python中pil模块的使用技巧,并Image.fromstring函数进行了较为详尽的分析说明,需要...

    疯狂一夏12162019-12-03
  • PythonPython socket模块实现的udp通信功能示例

    Python socket模块实现的udp通信功能示例

    这篇文章主要介绍了Python socket模块实现的udp通信功能,结合具体实例形式分析了Python使用socket模块实现UDP通信客户端与服务器端相关实现技巧,需要的朋友可...

    xuezhangjun7092021-06-14
  • Pythonpython绘图pyecharts+pandas的使用详解

    python绘图pyecharts+pandas的使用详解

    这篇文章主要介绍了python绘图pyecharts+pandas的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们...

    ElTarget12992021-08-13
  • Pythonpython测试框架unittest和pytest区别

    python测试框架unittest和pytest区别

    这篇文章主要介绍了python测试框架unittest和pytest区别,帮助大家更好的理解和学习使用python进行自动化测试,感兴趣的朋友可以了解下...

    蘇小柒10182021-10-15
  • PythonPython标准库之Sys模块使用详解

    Python标准库之Sys模块使用详解

    这篇文章主要介绍了Python标准库之Sys模块使用详解,本文讲解了使用sys模块获得脚本的参数、处理模块、使用sys模块操作模块搜索路径、使用sys模块查找内建...

    Python教程网7022020-07-06