Django_渲染详解

Django_render

模板语法

模板引擎是一种可以让开发者把服务端数据填充到html网页中完成渲染效果的技术。它实现了把前端代码和服务端代码分离的作用,让项目中的业务逻辑代码和数据表现代码分离,让前端开发者和服务端开发者可以更好的完成协同开发。

静态网页:页面上的数据都是写死的,万年不变
动态网页:页面上的数据是从后端动态获取的(比如后端获取当前时间;后端获取数据库数据然后传递给前端页面)

Django框架中内置了web开发领域非常出名的一个DjangoTemplate模板引擎(DTL)。DTL官方文档

要在django框架中使用模板引擎把视图中的数据更好的展示给客户端,需要完成3个步骤:

  1. 在项目配置文件中指定保存模板文件的模板目录。一般模板目录都是设置在项目根目录或者主应用目录下。
  2. 在视图中基于django提供的渲染函数绑定模板文件和需要展示的数据变量
  3. 在模板目录下创建对应的模板文件,并根据模板引擎内置的模板语法,填写输出视图传递过来的数据。

配置模板目录:在当前项目根目录下创建了模板目录templates. 然后在settings.py, 模板相关配置,找到TEMPLATES配置项,填写DIRS设置模板目录。

render内部本质

Django_渲染详解
def index(request):
    name = "hello world!"
    # 1. 初始化模板,读取模板内容,实例化模板对象
    # get_template会从项目配置中找到模板目录,我们需要填写的参数就是补全模板文件的路径
    template = get_template("index.html")
    # 2. 识别context内容, 和模板内容里面的标记[标签]替换,针对复杂的内容,进行正则的替换
    context = {"name": name}
    content = template.render(context, request) # render中完成了变量替换成变量值的过程,这个过程使用了正则。
    print(content)
    # 3. 通过response响应对象,把替换了数据的模板内容返回给客户端
    return HttpResponse(content)
    # 上面代码的简写,直接使用 django.shortcuts.render
    # return render(request, "index.html",context={"name":name})
    # return render(request,"index3.html", locals())
    # data = {}
    # data["name"] = "xiaoming"
    # data["message"] = "你好!"
    # return render(request,"index3.html", data)
  1. DTL模板文件与普通html文件的区别在哪里?

DTL模板文件是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。

  1. 开发中,我们一般把开发中的文件分2种,分别是静态文件和动态文件。
  2. 静态文件,数据保存在当前文件,不需要经过任何处理就可以展示出去。普通html文件,图片,视频,音频等这一类文件叫静态文件。
  3. 动态文件,数据并不在当前文件,而是要经过服务端或其他程序进行编译转换才可以展示出去。 编译转换的过程往往就是使用正则或其他技术把文件内部具有特殊格式的变量转换成真实数据。 动态文件,一般数据会保存在第三方存储设备,如数据库中。django的模板文件,就属于动态文件。

模板语法内容

  1. 变量渲染(深度查询、过滤器)
{{val}}
{{val|filter_name:参数}}
  1. 标签
{% tag_name %}
  1. 嵌套和继承

1.1 深度查询

def index(request):
    name = "ZhangJR"
    age = 22
    is_married = True
    course = ["global education","hongkong economy"]

    regina = {
        "name":"ZhangJR",
        "age": 22,
        "is_married": True,

    }

    class info():
        def __init__(self,name,age):
            self.name = name
            self.age = age
    Info = info("ZhangJR",22)

    Info1 = info("ZhangJR",22)
    Info2 = info("regina", 23)
    Info3 = info("ivnalee", 24)
    Info4 = info("qianniu", 25)
    Infos = [Info1,Info2,Info3,Info4]

    return render(request,"index.html",locals())

深度查询在查询属性或者取值的过程都用 .作为判断,locals函数代表将视图函数所有的内容全部传送给模板文件渲染
分别通过普通类型,字典类型,类,类的列表进行学习

深度查询:句点符"."
普通类型
姓名:{{name}}
年龄:{{age}}
婚否:{{is_married}}
课程:{{course}}
第一个课程:{{course.0}}

字典
个人信息:{{regina}}
个人名字:{{regina.name}}
个人年龄:{{regina.age}}

类对象
类对象名字:{{Info.name}}
类对象年龄:{{Info.age}}

类列表取值
第二个人的姓名:{{Infos.1.name}}

Django_渲染详解

1.2 内置过滤器

语法:

{{obj|过滤器名称:过滤器参数}}

内置过滤器

过滤器 用法 代码 last 获取列表/元组的最后一个成员 {{list | last}} first 获取列表/元组的第一个成员 {{list|first}} length 获取数据的长度 {{list | length}} default 当变量没有值的情况下, 系统输出默认值, {{str|default:”默认值”}} safe 让系统不要对内容中的html代码进行实体转义 {{htmlcontent| safe}} upper 字母转换成大写 {{str | upper}} lower 字母转换成小写 {{str | lower}} title 每个单词首字母转换成大写 {{str | title}} date 日期时间格式转换 {{ value cut 从内容中截取掉同样字符的内容 {{content | cut:"hello"}} list 把内容转换成列表格式 {{content | list}} add 加法 {{num| add}} filesizeformat 把文件大小的数值转换成单位表示 {{filesize | filesizeformat}}join`

按指定字符拼接内容 {{list| join(“-“)}} random

随机提取某个成员 {list | random}} slice

按切片提取成员 {{list | slice:”:-2″}} truncatechars

按字符长度截取内容 {{content | truncatechars:30}} truncatewords

按单词长度截取内容 同上

Infos = [Info1.name,Info2.name,Info3.name,Info4.name]
信息的最后一个人的姓名:{{Infos | last}}
信息的第一个人的姓名:{{Infos | first}}
共有{{Infos | length}}个人

Django_渲染详解
  • 默认值 如果渲染的值为空,可以添加默认渲染值,效果如图
Name= ""

姓名{{Name}}

Django_渲染详解

如果变成 <p>&#x59D3;&#x540D; {{Name|default:"regina"}}</p>(default后面不能有空格)

Django_渲染详解
  • 日期转换
now = datetime.datetime.now()
 当前时间默认格式:{{now}}
 格式化日期:{{now|date:"Y-m-d"}}
 格式化日期2:{{now|date:"D/d/m/Y"}}

Django_渲染详解
* 文件大小 filesizeformat过滤器自动会识别字节大小进行单位的选择
 file1 = 717
  file2 = 127717
  file3 = 1271221
  file4 = 1155178797
 文件大小:{{file1|filesizeformat}}
 文件大小:{{file2|filesizeformat}}
 文件大小:{{file3|filesizeformat}}
 文件大小:{{file4|filesizeformat}}

Django_渲染详解
* 按字符截断
str = "ABCDEFGHIJK"
 content: {{str | truncatechars:6}}

Django_渲染详解

这个…默认算作了一个字符
* safe过滤 如果我们输入的是一段带有标签的html语言,类似于

    link = "cuhk"
    script = "alert('regina')"

Django_渲染详解
 link:{{link| safe}}
 script:{{script|safe}}

Django_渲染详解

1.3 自定义过滤器

虽然官方已经提供了许多内置的过滤器给开发者,但是很明显,还是会有存在不足的时候。例如:希望输出用户的手机号码时, 13912345678 —->> 139*****678,这时我们就需要自定义过滤器。要声明自定义过滤器并且能在模板中正常使用,需要完成2个前置的工作:

  1. 当前使用和声明过滤器的子应用必须在setting.py配置文件中的INSTALLED_APPS中注册了!!!
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Django_渲染详解
Django_渲染详解
from django import template
register = template.Library()

@register.filter("mobile")
def mobile(number):
    return number[:3]+"****"+number[-3:]

Django_渲染详解

2.1 标签

{% tagname %}

if标签

is_married = True
{% if is_married == True %}
    张女士已婚
{% else %}
    张女士未婚
{% endif %}

这里需要注意的几个点:

  1. {% if condition %}这里的condition和if都需要和周围的%空开一格
  2. {% if is_married == true %}这里要用双等号
  3. 最后一定要加

Django_渲染详解

    {% if age < 20 %}
        太小
    {% elif age < 22 %}
        还行
    {% else %}
        正好
    {% endif %}

for循环


    {% for name in course %}
    {{ name }}
    {% endfor %}

Django_渲染详解

        序号
        姓名
        年龄

{% for info in Infos %}

        {{ forloop.counter }}
        {{ info.name }}
        {{ info.age }}

{% endfor %}

Django_渲染详解

还可以结合if判断

{% for info in Infos %}
    {% if forloop.first %}

        {{ forloop.counter }}
        {{ info.name }}
        {{ info.age }}

    {% else %}

            {{ forloop.counter }}
            {{ info.name }}
            {{ info.age }}

    {% endif %}

{% endfor %}

Django_渲染详解

或者还可以

    {% elif info.age > 23 %}

            {{ forloop.counter }}
            {{ info.name }}
            {{ info.age }}

Django_渲染详解

循环中, 模板引擎提供的forloop对象,用于给开发者获取循环次数或者判断循环过程的.

属性 描述 forloop.counter 显示循环的次数,从1开始 forloop.counter0 显示循环的次数,从0开始 forloop.revcounter0 倒数显示循环的次数,从0开始 forloop.revcounter 倒数显示循环的次数,从1开始 forloop.first 判断如果本次是循环的第一次,则结果为True forloop.last 判断如果本次是循环的最后一次,则结果为True forloop.parentloop 在嵌套循环中,指向当前循环的上级循环

3 嵌套继承

传统的模板分离技术,依靠{% include “模板文件名”%}实现,这种方式,虽然达到了页面代码复用的效果,但是由此也会带来大量的碎片化模板,导致维护模板的成本上升.因此, Django框架中除了提供这种模板分离技术以外,还并行的提供了 模板继承给开发者.

{% include "模板文件名"%}  # 模板嵌入
{% extends "base.html" %} # 模板继承

3.1 include

假设现在有两个页面公用一个同样式的东西,即页面底部有一个广告~

Django_渲染详解

在每一个页面里都添加一句

{% include "same.html" %}

Django_渲染详解

Django_渲染详解

此时两个页面就同时拥有了这一元素

3.2 extends继承

因为一个页面继承的东西可能有很多,而且有很多的固定框架,不可能每一个都用include进行继承,此时就需要extends关键字,首先我们来用bootstrap学习一下,然后在我们需要自己渲染的位置上添加区块


     {% block content %}
     hello world!

     {% endblock %}

其中content是自定义的名字,在模板文件里也同样要用这个名字,然后在其他文件里进行导入这个文件

{% extends "same.html" %}
.....

{% block content %}
原来渲染的内容
{% endblock %}

被extends的文件在未使用时是这样的

Django_渲染详解

我们看到有两个块是要传递给模板文件渲染的, index.htmltest.html同时继承了这一文件,效果如图

Django_渲染详解

Django_渲染详解
  • 如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。
  • 在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。
  • 为了更好的可读性,你也可以给你的 {% endblock %} 标签一个 名字 。例如: {%block content%}...{% endblock content%},在大型模版中,这个方法帮你清楚的看到哪一个 {% block %} 标签被关闭了。
  • 不能在一个模版中定义多个相同名字的 block 标签。

在最开始的same页面中,我们是添加了一句话的,虽然这句话并不重要,但是如果我们继承的时候也想要这句话,就需要把语句改为

{% block content %}
{{ block.super }}
....

Django_渲染详解

此时原来 same.html里面的block内容也可以得到继承

Original: https://www.cnblogs.com/ivanlee717/p/16695109.html
Author: ivanlee717
Title: Django_渲染详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/582557/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • WPF 切换主题使用 luna 复古版本

    本文告诉大家如何在 WPF 里面使用 luna 等复古主题 今天在 lsj 说他准备优化 WPF 的程序集时,准备删除 luna 等程序集时,找到了一段有趣的注释,发现在 WPF …

    Linux 2023年6月6日
    083
  • 微信公众号开发之获取微信用户的openID

    (注:openID同一用户同一应用唯一,UnionID同一用户不同应用唯一。不同应用指微信开放平台下的不同用户。) 1、 申请测试号(获得appID、appsecret) 2、 填…

    Linux 2023年6月13日
    080
  • 路由黑洞和黑洞路由

    路由黑洞: 路由黑洞一般是在网络边界做汇总回程路由的时候产生的一种不太愿意出现的现象,就是汇总的时候有时会有一些网段并不在内网中存在,但是又包含在汇总后的网段中,如果在这个汇总的边…

    Linux 2023年6月14日
    0112
  • 【Example】C++ 模板概念讲解及编译避坑

    C++ 不同于 Java,它没有标准的 Object 类型。也就意味着 C++ 并不存在完整的泛型编程概念。 为什么不存在完整的泛型编程概念,放到最后一个例子讲,先讲 &#8220…

    Linux 2023年6月13日
    089
  • phpcms安装

    【快速安装开始】 下载解压phpcms,复制安装文件到站点目录”/opt/html”里,给予权限(官网无法访问了,所以下载地址需自行寻找上传) cd /us…

    Linux 2023年6月6日
    078
  • 【转】京东评价系统海量数据存储设计

    概述 京东的商品评论目前已达到数十亿条,每天提供的服务调用也有数十亿次,而这些数据每年还在成倍增长,而数据存储是其中最重要的部分之一,接下来就介绍下京东评论系统的数据存储是如何设计…

    Linux 2023年6月16日
    0133
  • 【设计模式】Java设计模式-桥接模式

    【设计模式】Java设计模式 – 桥接模式 😄 不断学习才是王道🔥 继续踏上学习之路,学之分享笔记👊 总有一天我也能像各位大佬一样🏆原创作品,更多关注我CSDN: 一个…

    Linux 2023年6月6日
    0129
  • Centos-Stream 配置本地yum源和配置阿里云yum源

    镜像下载、域名解析、时间同步请点击阿里云开源镜像站 一、配置本地yum源 1. 挂载iso 2.创建目录并挂载iso 该文件按以下方式修改,有六处更改 [En] The file …

    Linux 2023年5月27日
    0126
  • 通过启动脚本控制PHP-FPM开关

    vi /etc/init.d/php-fpm 复制粘贴以下内容: ! /bin/sh Comments to support chkconfig on CentOSchkconfi…

    Linux 2023年6月6日
    089
  • lab 1

    int father[2],son[2]; int son[2]; if (fork() == 0) { int n; char buf[1]; close(0); dup(fat…

    Linux 2023年6月7日
    075
  • Vim配置文件-详解(.vimrc)

    Vim配置文件的作用 Vim启动时,会根据配置文件(.vimrc)来设置 Vim,因此我们可以通过此文件来定制适合自己的 Vim 所有系统用户在启动Vim时,都会加载这个配置文件。…

    Linux 2023年6月13日
    092
  • [编译] 9、在Linux下搭建 nordic 最新基于 zephyr 的开发烧写环境

    前言 1、概述 2、安装工具 3、获取 nRF Connect SDK 源码 4、安装 Python modules 5、安装 toolchain 6、下载 nRF Command…

    Linux 2023年6月8日
    087
  • 数据结构和算法的关系

    针对Python数据结构与算法(裘宗燕版)中的第一章绪论最后的问题 数据结构 概念 数据与数据之间的结构关系(数组、队列、树、图等结构) 类别 分为 逻辑数据结构和 存储数据结构两…

    Linux 2023年6月7日
    0139
  • WEB自动化-05-Cypress-元素交互

    5 元素交互 元素识别和操作是UI自动化测试的基础,下面一起来学习一下在Cypress中的元素交互操作吧。 5.1 元素定位器选择 每一个测试用例都包含对元素的定位识别和操作等。因…

    Linux 2023年6月7日
    0102
  • 使用 Powershell 删除N天前的文件

    在 Linux 中删除N天前的文件可以使用以下命令: find /path/to -maxdepth 1 -name "filename" -mtime +1 …

    Linux 2023年6月14日
    080
  • 《卡死你3000》批量文件复制命令详解

    卡死你3000简介: 名词解释: 批量顺序复制文件:从主控机,到从被控机1,被控机2,复制文件。有卡住问题。 批量并发复制文件:从主控机,到从被控机1,被控机2,复制文件。使用多线…

    Linux 2023年6月13日
    0120
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球