Python全栈之模板渲染详解

目录
  • 1.标签
    • 1.1for循环标签
    • 1.2if标签
    • 1.3with标签
    • 1.4csrftoken标签
  • 2.模板继承
  • 3.组件
  • 4.自定义过滤器
  • 5.自定义标签
  • 6.inclusion_tag自定义标签
  • 7.小提示与小练习
  • 总结

1. 标签

{% 标签 %}

1.1 for循环标签

<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对象

<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标签

{% 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判断,注意条件两边都有空格。

注意:不能像下面这样写

{% if a > b > c %}
...
{% endif %}

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

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

1.3 with标签

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

写法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标签

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

2. 模板继承

先创建一个母版(模板)

比如base.html

<!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块(叫做 钩子)

{% block content %}
	<h1>基础模板</h1>
{% endblock %}

子页面中继承模板extends

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

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

{% extends 'base.html' %}
{% block css %}
    <style>
        .c1{
            background-color: green;
            height: 40px;
        }
    </style>
{% endblock %}
{% block content %}
    <h1>性感美女,在线指导</h1>
    {{ block.super }} <!-- 显示模板的内容 -->
{% endblock %}

block块的写法

{% block content %}
...
{% endblock %}
{% block content %}
...
{% endblock content %}    可以指定endblock的名称,起到一个提示作用

3. 组件

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

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

<!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

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

<!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文件中加上如下配置

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

<!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:

{% 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文件中写如下内容

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文件中使用

{% 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文件中写如下内容

from django import template
register = template.Library()  #注册器,变量名称必须叫register

@register.simple_tag
def tag1(v1, v2 ,v3):  #参数个数没有限制
	return v1 + v2 + v3

4 在html文件中使用

{% 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文件中写如下内容

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

<!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

{% 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页面是可以传入动态数据

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. 小提示与小练习

小提示

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

小练习

页面效果

总结

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

(0)

相关推荐

  • Python数据结构与算法中的栈详解(2)

    目录 匹配括号 匹配符号 总结 匹配括号 接下来,我们使用栈解决实际的计算机科学问题.​ 比如我们都写过这样所示的算术表达式, ( 5 + 6 ) ∗ ( 7 + 8 ) / ( 4 + 3 ) (5 + 6) * (7 + 8) / (4 + 3) (5+6)∗(7+8)/(4+3),其中的括号用来改变计算顺序,或提升运算优先级.​ 匹配括号是指每一个左括号都有与之对应的一个右括号,并且括号对有正确的嵌套关系. 正确的嵌套关系: ( ( ) ( ) ( ) ( ) ) (()()()()) (

  • python数据结构之栈、队列及双端队列

    目录 1.线性数据结构的定义 2.栈 2.1 栈的定义 2.2 栈的数据类型 2.3 用python实现栈 2.4 栈的应用 3. 队列 3.1 队列的定义 3.2 队列抽象数据类型 3.3 用python实现队列 3.3 队列的应用 4. 双端队列 4.1 双端队列的定义 4.2 双端队列抽象数据类型 4.3 用python实现双端队列 4.3 双端队列的应用 5.链表 5.1 链表定义 5.2 用python实现链表 前文学习: python数据类型: python数据结构:数据类型. py

  • Python数据结构与算法中的栈(1)

    目录 什么是栈 构建一个栈 总结 什么是栈 栈有时也被称作“下推栈”.它是有序集合,添加操作和移除操作总发生在同一端,即栈的 “顶端”,栈的另一端则被称为 “底端”.所以最新添加的元素将被最先移除,而且栈中的元素离底端越近,代表其在栈中的时间越长. 这种排序原则被称作LIFO(last-in first-out),即后进先出.它提供了一种基于在集合中的时间来排序的方式. 最近添加的元素靠近顶端,旧元素则靠近底端. 栈的例子在日常生活中比比皆是.几乎所有咖啡馆都有一个由托盘或盘子构成的栈,你可以从

  • Python数据结构之栈详解

    目录 0.学习目标 1.栈的基本概念 1.1栈的基本概念 1.2栈抽象数据类型 1.3栈的应用场景 2.栈的实现 2.1顺序栈的实现 2.1.1栈的初始化 2.2链栈的实现 2.3栈的不同实现对比 3.栈应用 3.1顺序栈的应用 3.2链栈的应用 3.3利用栈基本操作实现复杂算法 0. 学习目标 栈和队列是在程序设计中常见的数据类型,从数据结构的角度来讲,栈和队列也是线性表,是操作受限的线性表,它们的基本操作是线性表操作的子集,但从数据类型的角度来讲,它们与线性表又有着巨大的不同.本节将首先介绍

  • 详解python数据结构之栈stack

    前言 栈(Stack)是一种运算受限的线性表. 按照先进后出(FILO,First In Last Out)的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶.栈只能在一端进行插入和删除操作. 文章内容包含: (1)栈的基本格式 (2)压栈 push_stack (3)出栈 pop_stack (4)取栈顶 peek_stack 一.栈的基本格式 class Stack(): def __init__ (self,size): self.size = size #栈空间大小 self.to

  • Python全栈之模板渲染详解

    目录 1.标签 1.1for循环标签 1.2if标签 1.3with标签 1.4csrftoken标签 2.模板继承 3.组件 4.自定义过滤器 5.自定义标签 6.inclusion_tag自定义标签 7.小提示与小练习 总结 1. 标签 {% 标签 %} 1.1 for循环标签 <ul> <!-- 可迭代对象都可以用循环 --> <!-- 循环列表 --> {% for foo in hobby %} <li>{{ foo }}</li> {

  • Python全栈之列表数据类型详解

    前言 列表(list)同字符串一样都是有序的,因为他们都可以通过切片和索引进行数据访问,且列表是可变的. 创建列表的几种方法 第一种 name_list = ['Python', 'PHP', 'JAVA'] 第二种 name_list = list(['Python', 'PHP', 'JAVA']) 创建一个空列表 >>> li = list() >>> type(li) <class 'list'> 把一个字符串转换成一个列表 >>>

  • Python全栈之协程详解

    目录 1. 线程队列 2. 进程池_线程池 3. 回调函数 4. 协程 总结: 1. 线程队列 # ### 线程队列 from queue import Queue """ put 存放 超出队列长度阻塞 get 获取 超出队列长度阻塞 put_nowait 存放,超出队列长度报错 get_nowait 获取,超出队列长度报错 """ # (1) Queue """先进先出,后进先出"""

  • Python OpenCV实现图像模板匹配详解

    目录 1.什么是模板匹配及模板匹配方法matchTemplate() 介绍 素材准备 2.单模板匹配 2.1 单目标匹配 2.2 多目标匹配 3.多模板匹配 1.什么是模板匹配及模板匹配方法matchTemplate() 介绍 提供一个模板图像,一个目标图像,且满足模板图像是目标图像的一部分,从目标图像中寻找特定的模板图像的过程,即为模板匹配.OpenCV提供了matchTemplate()方法帮助我们实现模板匹配. 该方法语法如下: cv2.matchTemplate(image, templ

  • Python+Opencv实现图像模板匹配详解

    目录 引言 一.匹配方法 二.匹配单个对象 三.匹配多个对象 引言 什么是模板匹配呢? 看到这里大家是否会觉得很熟悉的感觉涌上心头!在人脸识别是不是也会看见 等等. 模板匹配可以看作是对象检测的一种非常基本的形式.使用模板匹配,我们可以使用包含要检测对象的“模板”来检测输入图像中的对象. 一.匹配方法 cv2.matchTemplate(img, templ, method) 参数:(img: 原始图像.temple: 模板图像.method: 匹配度计算方法) 方法如下: cv2.TM_SQD

  • vue2从数据到视图渲染之模板渲染详解

    目录 引言 1.从new Vue()入口开始: 2.this._init 3.挂载函数vm.$mount(vm.$options.el) 4.mountComponent函数 5._render函数 6.createElement函数返回虚拟DOM 7._update函数 8.patch函数 9.createElm函数 10.移除 引言 一般使用html,css和javascript直接将数据渲染到视图中,需要关心如何去操作dom,如果数据量比较大,那么操作过程将会繁琐且不好控制.vue将这些操

  • Django零基础入门之模板变量详解

    引言: 我们在页面上会看到,谁登录的就会显示谁的信息,那么这个页面上的变量信息是怎样实现的呢? 这就是本文要讲述的内容--Django中的模板变量! 1.模板变量! 可以在前端页面中使用模板变量来取数据库中的数据,实现前端页面数据动态显示. (1)模板变量使用规则:(在HTML模板中使用!) 语法: {{ 变量名 }} 命名由字母和数字以及下划线组成,不能有空格和标点符号 可以使用字典.类对象.方法.函数.列表.字符串 不要和python或django关键字重名 注意: 如果data是一个字典,

  • python四则运算表达式求值示例详解

    目录 四则运算表达式求值 思路说明 算法步骤 代码 四则运算表达式求值 思路说明 使用双栈来实现——存放数值的栈 nums 与存放运算符的栈 ops. 算法步骤 对原始表达式字符串 exp 进行预处理, 将其转为一个元素对应一个数值或运算符的列表 explist. 遍历 explist , 每个元素依次压入对应的栈中. 每次压入后, 判断当前两栈顶是否可进行乘除运算.栈顶可进行乘除运算的充要条件是, ops 栈顶为<*> ,</> 之一, 且 nums 中的元素比 ops 中的元素

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

    很多人在群里问,这个下拉框定位不到.那个弹出框定位不到-各种定位不到,其实大多数情况下就是两种问题:1 有frame,2 没有加等待.殊不知,你的代码运行速度是什么量级的,而浏览器加载渲染速度又是什么量级的,就好比闪电侠和凹凸曼约好去打怪兽,然后闪电侠打完回来之后问凹凸曼你为啥还在穿鞋没出门?凹凸曼分分中内心一万只羊驼飞过,欺负哥速度慢,哥不跟你玩了,抛个异常撂挑子了. 那么怎么才能照顾到凹凸曼缓慢的加载速度呢?只有一个办法,那就是等喽.说到等,又有三种等法,且听博主一一道来: 1. 强制等待

  • VTK与Python实现机械臂三维模型可视化详解

    三维可视化系统的建立依赖于三维图形平台, 如 OpenGL.VTK.OGRE.OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成了开发难度大. 周期长等问题.VTK. ORGE.OSG等平台使用封装更好的函数简化了开发过程.下面将使用Python与VTK进行机器人上位机监控界面的快速原型开发. 完整的上位机程序需要有三维显示模块.机器人信息监测模块(位置/角度/速度/电量/温度/错误信息...).通信模块(串口/USB/WI

随机推荐