首页 > 其他分享 >第五章:模板层

第五章:模板层

时间:2023-01-17 22:00:24浏览次数:42  
标签:return 前端 html 第五章 过滤器 模板 页面

模板层

模板语法传值

{{ }}:传变量相关的值,如:整型、列表、字典、函数等等

{% %}:传逻辑相关的值,如:for循环、if判断、static动态解析等等

传递基本数据类型

整型、浮点型、字符串、布尔值、列表、字典、元组、集合,所有的Python数据类型都可以传

基本数据类型的取值

# Django模板语法的取值,是固定的格式,只能采用"句点符":"."
# 既可以点字典的建,可以点列表、元组等等的索引
<p>{{ l.2 }}</p>
<p>{{ d.name }}</p>
# 还可以两者混用
<p>{{ d.hobby.2.info }}</p>

def index(request):
    i = 111
    f = 1.1
    s = '你好'
    b = True
    l = [111, 'hello', [111]]
    d = {'name': 'liu', 'age': 12, 'hobby': [11, 22, {'info': 'NB'}]}
    t = (111, 222,)
    se = {111, 222}
    return render(request, 'index.html', locals())

传递函数

# 传递函数名会自动加括号调用,但是模板语法不支持给函数传递额外的参数

"""后端"""
def index(request):
    def func():
        print('我执行了')
        return '我是函数'
    return render(request, 'index.html', locals())
"""前端"""
<p>{{ func }}</p>

传递类和对象及对象内的方法

# 传递类名的时候也会加括号调用(实例化),也不支持传递参数
# 传递对象的时候可以点对象的方法,返回对应方法的返回值

"""后端"""
def index(request):
    class MyClass(object):
        def get_self(self):
            return 'self'

        @staticmethod
        def get_func():
            return 'func'

        @classmethod
        def get_class(cls):
            return 'class'

        # def __str__(self):
        #     return '类中的__str__方法'

    obj = MyClass()
    return render(request, 'index.html', locals())

"""前端"""
<p>{{ MyClass }}</p>  # <app01.views.index.<locals>.MyClass object at 0x0000000003EE90D0>
<p>{{ obj }}</p>  # <app01.views.index.<locals>.MyClass object at 0x0000000003ECC100>
<p>{{ obj.get_self }}</p>  # self
<p>{{ obj.get_func }}</p>  # func
<p>{{ obj.get_class }}</p>  # class

过滤器(过滤器最多接收两个参数)

# 过滤器类似于是模板语法内置的 内置方法
# Django内置有60多个过滤器,暂时了解10个左右

# 基本语法
{{ 数据|过滤器:参数 }}

safe:转义(可以识别字符串中的html代码)

"""模板语法默认是不识别字符串中的html代码的"""
# 第一种:前端过滤器转义
# 后端数据
hhh = '<h1>liu</h1>'
# 前端过滤器
<p>{{ hhh|safe }}</p>

# 第二种:后端转义
from django.utils.safestring import mark_safe
res = mark_safe('<h1>liujie</h1>')

<p>{{ res }}</p>


"""
有了这个过滤器后,在写全栈项目的时候,前端代码不一定要写在前端页面,也可以在后端先写好,然后传递给前端页面
"""

length:统计字符长度

# 后端数据
s = '你好'
# 前端过滤器
<p>{{ s|length }}</p>  # 2

default:默认值(第一个参数布尔值为True就展示第一个参数,反之则为后面的值)

# 后端数据
b = True
# 前端过滤器
<p>{{ b|default:'False' }}</p>  # True

filesizeformat:计算文件大小

# 后端数据
i = 111546165498
# 前端过滤器
<p>{{ i|filesizeformat }}</p>  # 103.9 GB

date:格式化时间(把人类难以看清楚的时间改为人类易读的时间)

# 后端数据
import datetime
time = datetime.datetime.now()
# 前端过滤器
<p>{{ time|date:'Y-m-d H:i:s' }}</p>  # 2023-01-14 17:25:59

slice:切片操作,支持步长

# 后端数据
s = 'daasdasd'
# 前端过滤器
<p>{{ s|slice:'0:4:2' }}</p>  # da

truncatechars:切取字符(包含三个点)

# 后端数据
info = '多发的发放阿萨德发顺丰阿斯顿发份'
# 前端过滤器
<p>{{ info|truncatechars:9 }}</p>  # 多发的发放阿...

truncatewords:切取单词(按照空格切,不包含三个点)

# 后端数据
info = '多 发 的 发放 阿萨 德发顺丰 阿斯顿发份'
# 前端过滤器
<p>{{ info|truncatewords:5 }}</p>  # 多 发 的 发放 阿萨 ...

cut:移除指定的字符

# 后端数据
info = '多 发 的 发放 阿萨 德发顺丰 阿斯顿发份'
# 前端过滤器
<p>{{ info|cut:' ' }}</p>  # 多发的发放阿萨德发顺丰阿斯顿发份

join:按照指定的字符进行拼接

# 后端数据
l = [111, 'hello', [111]]
# 前端过滤器
<p>{{ l|join:'-' }}</p>  # 111-hello-[111]

add:拼接(字符与字符拼接,数字与数字做加法运算)

"""
字符与字符是做拼接,数字与数字是做加法
字符与数字不能拼接
"""
# 后端数据
i = 111
s = 'daasdasdfsfsfsdfsd'
info = '多 发 的 发放 阿萨 德发顺丰 阿斯顿发份'
# 前端过滤器
<p>{{ i|add:10 }}</p>  # 121
<p>{{ s|add:info }}</p>  # daasdasdfsfsfsdfsd多 发 的 发放 阿萨 德发顺丰 阿斯顿发份

标签

for循环

语法

{% for 属性名 in 可迭代对象 %}
    <p>{{  }}</p>
{% endfor %}

内置属性:forloop

{% for foo in l %}
    <p>{{ forloop }}</p>
{% endfor %}

# 浏览器展示的
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 3, 'revcounter0': 2, 'first': True, 'last': False}

"""forloop属性key的介绍"""
# counter0:表示当前元素的索引
# counter:表示当前元素所在容器的位数
# first:当前元素是容器中的第一个元素时value为True,其他情况value皆为False
# last:当前元素时容器中最后一个元素时value为False,其他情况value皆为True

empty:可迭代对象为空的时候总empty下面的代码

{% for lll in l %}
    <p>{{ lll }}</p>
    {% empty %}
    <p>可迭代对象里面没有元素,没法for循环的时候自动走empty</p>
{% endfor %}

循环列表

"""循环列表"""
# 后端数据
l = [111, 'hello', [111], 'liu', 'song']
# 前端
{% for lll in l %}
    <p>{{ lll }}</p>
{% endfor %}

循环字典

"""循环字典"""
# 后端数据
d = {'name': 'liu', 'age': 12, 'hobby': [11, 22, {'info': 'NB'}]}
# 前端
# 循环字典的key
{% for ddd in d.keys %}
    <p>{{ ddd }}</p>
{% endfor %}

# 循环字典的值
{% for ddd in d.values %}
    <p>{{ ddd }}</p>
{% endfor %}

# 字典的key和value组成一个元组   ('name', 'liu')
{% for ddd in d.items %}
    <p>{{ ddd }}</p>
{% endfor %}

if判断

{% if b %}
    <p>b的布尔值是True,展示该标签</p>
{% elif s %}
    <p>b的布尔值是False,s的布尔值是True,展示该标签</p>
{% else %}
    <p>b和s的布尔值都是False,展示该标签</p>
{% endif %}

for循环和if判断混用

# 后端数据
l = [111, 'hello', [111], 'liu', 'song']

# 前端代码
{% for foo in l %}
    {% if forloop.first %}
        <p>这是第一行数据</p>
    {% elif forloop.last %}
        <p>这是最后一行数据</p>
    {% else %}
        <p>{{ foo }}</p>
    {% endif %}
{% endfor %}

# 浏览器渲染出来的页面
这是第一行数据

hello

[111]

liu

这是最后一行数据

with:给数据起别名(变量名)

当一个数据要用"句点符"点多次时,可以给这个数据起一个别名,方便多次使用,就类似后端中的变量名

语法

{% with 数据 as 给数据起的别名 %}
    <p>在with内,用数据的别名可以直接访问到后端的数据,类似变量名</p>
{% endwith %}

实例

"""
下面的例子中"NB"这个数据被嵌套了很多层,当我们要重复使用这个数据时就可以用with给他起一个别名

"""
# 后端数据
d = {'name': 'liu', 'age': 12, 'hobby': [11, 22, {'info': 'NB'}]}

# 前端代码
{% with d.hobby.2.info as nb %}
    <p>{{ nb }}</p>
{% endwith %}

自定义过滤器、标签、inclusion_tag

要自定义过滤器、标签等要先做以下准备

"""
1、在应用下创建一个名字必须叫templatetags文件夹
2、在该文件夹内创建任意名称的py文件,例如:mytag.py
3、在刚刚创建的py文件内必须写下面两行代码
  from django import template

  register = template.Library()
4、在创建的py文件下写过滤器、标签、inclusion_tag
"""

自定义过滤器

语法

# 自定义过滤器
@register.filter(name='过滤器名字')
def 函数名(最多接收两个参数):
    return res

# 前端使用
{% load 创建的py文件 %}
<p>{{ 数据|自定义过滤器的名字:参数 }}</p>

实例

# 自定义过滤器
@register.filter(name='number_of_words')
# 统计小说字数的过滤器
def number_of_words(i):
    # 判断字符串内是否为整型
    if not i.isdigit():
        return ''
    # 把字符型转为整型
    i = int(i)
    # 判断字数是否大于一万
    if i < 10000:
        return i
    # i大于一万时除以一万并保留两位小数
    i = round(i / 10000, 2)
    # i转为字符型并加上单位万
    res = str(i) + '万'
    return res


# 前端
{% load mytag %}
<p>该图书共 {{ ii|number_of_words }} 字</p>

自定义标签

语法

# 自定义标签
@register.simple_tag(name='标签名')
def 函数名(可以接收多个参数):
    return res

# 前端使用
{% load 创建的py文件 %}
<p>{% 标签名 参数(每个参数之间要空一格) %}</p>

实例

# 自定义标签
@register.simple_tag(name='plus')
def plus(name, age, weight, height):
    return f'我叫{name},今年{age}岁,身高{weight}cm,体重{height}kg'

# 前端
{% load mytag %}
<p>{% plus 'dick' 18 180 70 %}</p>

自定义inclusion_tag

"""
内部原理
  先定义一个方法
  在页面调用该方法,并且可以传值
  该方法会生成一些数据然后传递给一个html页面
  之后将渲染好的结果放到调用的位置
"""

语法

"""
括号内的html文件一般都不是完整的,没有html、body标签,只有需要传递给前端的标签
"""
# 自定义inclusion_tag
@register.inclusion_tag('html文件')
def 函数名(参数):
    data = []
    # 第一种传值方式
    # return {'data': data}  # 传值给上面括号内的html文件
    # 第二种传值方式
    return locals()  # 传值给上面括号内的html文件


# 使用
{% 函数名 '参数' %}

实例

# 自定义inclusion_tag
@register.inclusion_tag('show_list.html')
def show_list(n):
    # 列表生成式
    data = [f'第{i}项' for i in range(n)]
    # 第一种传值方式
    # return {'data': data}
    # 第二种传值方式
    return locals()


# 前端
{% show_list 10 %}


# show_list.html页面
# 整个html文件只写了这个标签
<ul>
    {% for i in data %}
        <li>{{ i }}</li>
    {% endfor %}
</ul>


# 展示到浏览器的
第0项
第1项
第2项
第3项
第4项
第5项
第6项
第7项
第8项
第9项

inclusion_tag总结

当html页面某一个地方的页面需要传参才能动态的渲染出来,并且多个页面上都需要使用到该局部时,那么就可以考虑将该局部页面做成inclusion_tag的形式

模板的继承

有的网站整体都差不多,只是某一些局部在做变化,这就是用到了模板的继承

语法

1、继承一个html页面
# 新建一个html文件,清空所有的内容,在里面写
{% extends '要继承的html页面' %}

2、划定主页面(被继承的html页面)中可以被修改的区域
# 子页面继承了主页面后,跟主页面是一模一样的,需要在主页面上提前划定可以被修改的区域
{% block '起一个模板名' %}
	模板内容
{% endblock %}

3、子页面修改划定区域的内容
# 子页面先声明要修改那一块区域,然后再修改
{% block '模板名' %}
    子页面内容
{% endblock %}

4、子页面继续使用主页面的内容
# 子页面除了可以自己写自己的内容以外,还可以继续使用主页面的内容
{% block '模板名' %}
    {{ block.super }}
    子页面内容
{% endblock %}


"""
一般情况下模板页面至少应该有三块可以被修改的区域
  1、css区域
  2、html区域
  3、js区域
"""
{% block css %}
    css代码
{% endblock %}

{% block content %}
    html局部的代码
{% endblock %}

{% block js %}
    js代码
{% endblock %}

"""
一般情况下,模板页面上划定的区域越多,那么该模板的扩展性就越高,但是如果太多那还不如重新写一个页面
"""

实例

// 模板页面(主页面)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!--引入jQuery的js文件t-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
    <!--引入bootstrap的js文件-->
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <!--引入bootstrap的css文件-->
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <title>Title</title>
    {% block css %}
        <style>
            h1 {
                color: red;
            }
        </style>
    {% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Brand</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                <li><a href="#">Link</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">Dropdown <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="#">Another action</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Separated link</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">One more separated link</a></li>
                    </ul>
                </li>
            </ul>
            <form class="navbar-form navbar-left">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="Search">
                </div>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">Link</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">Dropdown <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="#">Another action</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Separated link</a></li>
                    </ul>
                </li>
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
<div class="container">
    <div class="row">
        <div class="col-md-3">
            <ul class="nav nav-pills nav-stacked">
                <li role="presentation" class="active"><a href="/home/">主页面</a></li>
                <li role="presentation"><a href="/login/">登录</a></li>
                <li role="presentation"><a href="/reg/">注册</a></li>
            </ul>
        </div>
        <div class="col-md-9">
            {% block home %}
                <h1 class="text-center">首页</h1>
                <div class="jumbotron">
                    <h1>Hello, world!</h1>
                    <p>...</p>
                    <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
                </div>
            {% endblock %}
        </div>
    </div>
</div>
{% block js %}
    <script>
        alert('首页')
    </script>
{% endblock %}
</body>

</html>


// 子页面一
{% extends 'home.html' %}
{% block home %}
    <h1 class="text-center">登录</h1>
    <form action="">
        <p>账号:<input type="text" class="form-control"></p>
        <p>密码:<input type="password" class="form-control"></p>
        <p><input type="submit" value="登录" class="form-control btn btn-success"></p>
    </form>

{% endblock %}
{% block css %}
    <style>
        h1 {
            color: green;
        }
    </style>
{% endblock %}
{% block js %}
    <script>
        alert('登录页面')
    </script>
{% endblock %}

// 子页面二
{% extends 'home.html' %}
{% block home %}
    <h1 class="text-center">注册</h1>
    <form action="">
        <p>账号:<input type="text" class="form-control"></p>
        <p>密码:<input type="password" class="form-control"></p>
        <p><input type="submit" value="注册" class="form-control btn btn-danger"></p>
    </form>

{% endblock %}
{% block css %}
    <style>
        h1 {
            color: yellow;
        }
    </style>
{% endblock %}
{% block js %}
    <script>
        alert('注册页面')
    </script>
{% endblock %}

模板的导入

"""
将页面的某一个局部当成模块的形式
那个地方需要就可以直接导入使用
"""
{% include 要导入的局部 %}

{% include 'login.html' %}

标签:return,前端,html,第五章,过滤器,模板,页面
From: https://www.cnblogs.com/liuhousheng/p/17058778.html

相关文章

  • C#-使用模板导出Word文件
    记录下使用C#+Word模板导出Word文件的方法。首先建立Word文件模板,需要填写的地方用占位符替代,比如姓名处:name,年龄处:age....首先引入命名空间:usingword=Microsoft......
  • C++ 可变参模板
    求多个数的最小值template<typenameT,typename...Ts>constexprautomin(constT&a,constT&b,constTs&...ts){constautom=a<b?a:b;ifco......
  • SFINAE - 模板中的enable_if
    ref:https://github.com/wuye9036/CppTemplateTutorial#323-特化一些其它问题这段就是说:这个int实参在替换第一个inc_counter时,enable_if<false>,所以直接替换失败。......
  • 【加密与解密】第五章①
    序列号保护方式序列号保护机制软件验证序列号,其实就是验证用户名和序列号之间的数学映射关系。1.将用户名等信息作为自变量,通过函数F变换之后得到注册码这是非常不安......
  • AC自动机模板
    P3808【模板】AC自动机#include<bits/stdc++.h>usingnamespacestd;constintM=1e6+5;intch[M][26],cnt[M],fail[M],tot;voidinsert(char*s){//字典树的建......
  • 2023.1.16[模板] 二次剩余
    2023.1.16二次剩余问题叙述给出N,p,求解方程$x^2\equivN$(\(modp\))且保证p是奇素数。算法流程解的数量首先,探究$x^2\equivN$这个方程解的数量,假设我们......
  • 13.(行为型模式)java设计模式之模板模式
    一、什么是模板模式定义⼀个操作中的算法⻣架,将算法的⼀些步骤延迟到⼦类中,使得⼦类可以不改变该算法结构的情况下重定义该算法的某些特定步骤,属于⾏为型模式二、模板模......
  • 微信公众号开发之模板消息
     欢迎留言、转发微信极速开发系列文章:​​点击这里​​最近有点小感冒,文章的更新进度延误了一些,希望此系列文章对你​​研究微信公众开发​​​有帮助。前几篇文章介绍了微......
  • 二分算法查找模板
    这个是acwing站长YXC的模板https://www.acwing.com/file_system/file/content/whole/index/content/3073/版本1当我们将区间[l,r]划分成[l,mid]和[mid+1,r]时,其更......
  • 2023.1.16[模板]BSGS/exBSGS
    2023.1.16[模板]BSGS/exBSGS全称BoyStepGirlStep给定一个质数p,以及一个整数a,一个整数b,现在要求你计算一个最小的非负整数l,满足\(a^x\equivb(modp)\)算法......