在django中,模板引擎(DTL)是一种可以让开发者将服务端数据填充到html页面中的完成渲染的技术

模板引擎的原理分为以下三步:

  • 在项目配置文件中指定保存模板文件的的模板目录,一般设置在项目根目录或者子应用目录下

  • 在模板目录下创建对应的模板文件

  • 在视图函数中通过render函数绑定模板文件和需要渲染的数据

1.模板目录

在简单的项目中,我们通常在项目的根目录下创建名为templates的文件夹,并在配置文件中设置模板目录

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / "templates", ], # 设置主项目的模板文件所在路径
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

如果是多app的情况下,我们不仅要设置主模板目录,还要在每个app下创建对应的templates,包含该子app所需要的模板文件

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / "templates", ], # 设置主项目的模板文件所在路径
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

 

提示:在使用模板的时候,django会到主模板目录下寻找,找不到会按照顺序到已注册的项目下的模板目录中寻找

简单案例

路由

from django.contrib import admin
from django.urls import path, include
from apps.app01 import views urlpatterns = [
path('admin/', admin.site.urls),
path('book/',views.index)
]

视图

def index(request):
return render(request, 'app01/index.html')

模板

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> </body>
</html>

2.render函数的本质

render函数的本质就是将模板文件中的所有变量替换成后端数据,生成一个html页面,也就是纯文本,响应给客户端

模板文件 & html页面的区别

模板文件是含有特殊语法的html文件,这个语法可以被django的DTL编译,将数据传进,实现动态话,渲染之后的模板文件也就是一个普通的html文件了

开发中我们常将普通的html称之为静态文件,将模板文件称之为动态文件

视图函数

def index(request):
name = 'kunmzhao'
return render(request, 'app01/index.html', {'name':name}) # 将数据传递给模板文件

模板文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ name }}</p> #含有模板语法
</body>
</html>

渲染之后的html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>kunmzhao</p> # 渲染之后
</body>
</html>

3.模板语法

3.1 句点符

变量渲染可以将对象原封不动的渲染在页面

 def index(request):
# 字符串
name = 'kunmzhao'
# 数字
age = 18
# 列表
course = ['语文', '数学', '英语']
# 元组
hobby = ('篮球', '足球')
# 字典
parents = {'father': 'mayun', 'mother': "dongmingzhu"}
# 集合
teachers = {'alex', 'victor'} return render(request, 'app01/index.html', {
'name': name,
'age': age,
'course': course,
'hobby': hobby,
'parents': parents,
'teachers': teachers,
}

句点符就可以访问对象中的属性

from django.shortcuts import render, HttpResponse

# Create your views here.
class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age def index(request):
# 字符串
name = 'kunmzhao'
# 数字
age = 18
# 列表
course = ['语文', '数学', '英语']
# 字典
parents = {'father': 'mayun', 'mother': "dongmingzhu"} # 对象
dog = Animal('rubby', 3) return render(request, 'app01/index.html', {
'name': name,
'age': age,
'course': course,
'parents': parents,
'dog': dog
}
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ name }}</p>
<p>{{ age }}</p>
<p>{{ course.0 }}</p> # 访问列表第几个元素
<p>{{ course.1 }}</p>
<p>{{ course.2 }}</p>
<p>{{ parents.father}}</p> # 访问字典中键对应的值
<p>{{ parents.mother }}</p>
<p>{{ dog.name }}</p> # 访问对象发的属性
<p>{{ dog.age }}</p> </body>
</html>

3.2 过滤器

3.2.1 内置过滤器

内置过滤器最多有一个参数

语法:

{{obj|过滤器名称:过滤器参数}}
过滤器 用法 代码
last 获取列表/元组的最后一个成员 {{liast | last}}
first 获取列表/元组的第一个成员 {{list|first}}
length 获取数据的长度 {{list | length}}
defualt 当变量没有值的情况下, 系统输出默认值, {{str|default="默认值"}}
safe 让系统不要对内容中的html代码进行实体转义 {{htmlcontent| safe}}
upper 字母转换成大写 {{str | upper}}
lower 字母转换成小写 {{str | lower}}
title 每个单词首字母转换成大写 {{str | title}}
date 日期时间格式转换 {{ value| date:"D d M Y" }}
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 按单词长度截取内容 同上
def index(request):
name = 'kunmzhao'
hobby = ['篮球', '足球'] return render(request, 'app01/index.html', {
'name': name,
'hobby': hobby,
}
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ name|upper }}</p>
<p>{{ hobby|first }}</p>
<p>{{ hobby|last }}</p>
</body>
</html>

3.2.2 自定义过滤器

内置的过滤器可能没办法满足开发需求,django中支持使用自定义的过滤器

  • 确保定义过滤器所在的app已经注册

  • 在注册的app下创建templatetags的模块包

  • 创建py文件

  • 在文件中自定义过滤器

    from django import template
    
    register = template.Library()
    
    # 自定义过滤器
    @register.filter()
    def mobile(content):
    return content[:3] + "*****" + content[-3:]
  • 在模板中load过滤器并使用
    {% load my_filter %}  # 导入自定义的过滤器
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <p>{{ phone|mobile }}</p> # 使用过滤器
    </body>
    </html>

3.3 标签渲染

3.3.1 if

语法:

{% if 条件 %}
{%endif %}

视图

def index(request):
score = 80
return render(request, 'app01/index.html', {
'score': score,
}
)

模板

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if score > 90 %}
<p>成绩优秀啊</p>
{% elif score > 80 %}
<p>成绩良好</p>
{% else %}
<p>成绩一般</p>
{% endif %}
</body>
</html>

3.3.2 for

语法

{% for i in iter %}
{%endfor %}

for标签中常用的方法

forloop.counter  : 从1开始每次循环自增1
forloop.counter0 : 从0开始每次循环自增1
forloop.first : 是否是第一次循环
forloop.last : 是否是最后一循环

视图

def index(request):
hobby = ['篮球', '足球', '乒乓球']
return render(request, 'app01/index.html', {
'hobby': hobby,
}
)

模板

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for foo in hobby %} <p><span>{{ forloop.counter }}</span>{{ foo }}</p>
{% endfor %} </body>

4.模板自定义

  • filter

    见自定义过滤器
    参数:1-2个
  • Simple_tag
    返回文本
    参数:无限制
  • Inclusion_tag
    返回html片段
    参数无限制

定义

# encoding:utf-8
# author:kunmzhao
# email:1102669474@qq.com
from django import template register = template.Library() # 自定义过滤器
@register.filter()
def mobile(content):
return content[:3] + "*****" + content[-3:] # 自定义simple_tag
@register.simple_tag()
def mytag(a1, a2):
return a1 + a2 # 自定义inclusion_tag
@register.inclusion_tag("app01/menu.html")
def my_inclusion():
return {'name': 'kunmzhao', 'age': 18}

模板

{% load my_filter %}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ phone |mobile }}</p> # 使用自定义的过滤器
<p>{% mytag 100 200 %}</p> # 使用自定义的tag函数
<p>{% my_inclusion %}</p> # 使用自定义的inclusion_tag </body>
</html>

menu.html

<p>
<span>name={{ name }}</span>
<span>age={{ age }}</span>
</p>

5.模板继承和导入

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

5.1 继承

语法
{%entends 模板文件%} # 继承指定的模板文件 {% block 名称 %} # 填充模板中的某一个block {% endblock %}

视图

def index(request):
return render(request, 'app01/header.html')

模板header.html

{% extends 'app01/index.html' %}
{% block body%}
<div>不畏浮云遮望眼,只缘身在最高层</div>
{% endblock %}

模板index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% block css %}
{# css样式 #}
{% endblock %}
</head>
<body>
{% block body %}
{# 内容填充 #}
{% endblock %}
</body>
</html>

5.2 导入

    {% include 片段文件名%}

视图

def index(request):
return render(request, 'app01/header.html', {'name': 'kunmzhao', 'age': 18})

模板menu.html

<p>
<span>name={{ name }}</span>
<span>age={{ age }}</span>
</p>

模板header.html

{% extends 'app01/index.html' %}
{% block body %}
<div>不畏浮云遮望眼,只缘身在最高层</div>
{% include 'app01/menu.html' %} # 导入片段
{% endblock %}

6.静态文件

我们通常会将前端的css, js等代码发在app对应的static目录下,我们在模板中导入css或者js等代码的时候,引入{ %load static %}

跟templates类似,在多app下,我们通常会在每个app下创建一个static的文件夹,再创建对应app名字的文件件,将该app下使用的静态文件放在该目录

4.django-模板的更多相关文章

  1. Django模板与Vue.js冲突问题

    参考: https://my.oschina.net/soarwilldo/blog/755984 方法1:修改vue.js的默认的绑定符号 Vue.config.delimiters = [&quo ...

  2. 在 Django 模板中遍历复杂数据结构的关键是句点字符

    在 Django 模板中遍历复杂数据结构的关键是句点字符 ( . ). 实例二 mysit/templates/myhtml2.html修改如下 <!DOCTYPE html> <h ...

  3. python django 模板

    1 用两个大括号括起来的文字{{person_name}} 称为变量 2 被 大括号和面分号包围的文件({% if ordered_warranty %})是模板标签 3 过滤器是用管道符(|) 和U ...

  4. django 模板中定义临时列表

    <ul class="num_t clr"> {% for obj in ""|ljust:"10" %} <li> ...

  5. Django 模板中引用静态资源(js,css等)

    Django 模板中免不了要用到一些js和CSS文件,查了很多网页,被弄得略晕乎,还是官网靠谱,给个链接大家可以自己看英文的. https://docs.djangoproject.com/en/1. ...

  6. Django模板-分离的模板

    上一篇Django模板-在视图中使用模板最后的问题,我们需要把数据和展现分离开. 你可能首先考虑把模板保存在文件系统的某个位置并用 Python 内建的文件操作函数来读取文件内容. 假设文件保存在 E ...

  7. Django模板-在视图中使用模板

    之前我们已经有了自己的视图mysite.views.py中,应该是这样子的 from django.http import HttpResponse import datetime def curre ...

  8. Django模板-模板标签

    接着Django模板-基础知识继续写模板相关知识. if标签 {% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not ). 但是不允许在同一个 ...

  9. Django模板-基础知识

    上一篇中带参数的URLconf虽然可以做到传参动态显示内容,但是最终现实的内容还是硬编码到Python代码中的 def hours_ahead(request,phours): try: phours ...

  10. 关于Django模板引擎的研究

    原创博文,转载请注明出处. 以前曾遇到过错误Reverse for ‘*’ with arguments '()' and keyword arguments' not found.1其原因是没有给视 ...

随机推荐

  1. 【Azure Spring Cloud】Azure Spring Cloud服务,如何获取应用程序日志文件呢?

    问题描述 在使用Azure Spring Cloud服务时,如果要收集应用程序的日志.有控制台输出(实时流日志),也可以配置Log Analytics服务. 日志流式处理 可以通过以下命令在 Azur ...

  2. KingbaseES 的行列转换

    目录 背景 行转列 数据准备 分组聚合函数+CASE 根据压缩数据的格式,横向展开数据列选取不同方式 crosstab函数 PIVOT 操作符 PIVOT 操作符的限制 工具 ksql 的元命令 \c ...

  3. Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):5、Maven版本发布与后续版本更新(大结局)

    文章目录: Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):1.JIRA账号注册 Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):2.PGP ...

  4. 【Git进阶】基于文件(夹)拆分大PR

    背景 前段时间为了迁移一个旧服务到新项目,由此产生了一个巨大的PR,为了方便Code Review,最终基于文件夹,将其拆分成了多个较小的PR:现在这里记录下,后面可能还会需要. 演示 为了方便演示, ...

  5. 华南理工大学 Python第6章课后测验-2

    1.(单选)以下关于语句 a = [1,2,3,(4,5)]的说法中,正确的个数有( )个.(1)a是元组类型   (2)a是列表类型  (3)a有5个元素      (4)a有4个元素(5)a[1] ...

  6. Openstack Neutron : LBaaS v2

    目录 - LBaaS v2 - 负载均衡概念 - 服务器池 Pool - 监听器 Listener - L7 转发策略 l7 policy - 负载均衡算法 Algorithms - 健康监测 Mon ...

  7. 如何通过Java应用程序创建Word表格

    表格,又称为表,既是一种可视化交流模式,又是一种组织整理数据的手段.人们在通讯交流.科学研究以及数据分析活动当中广泛采用着形形色色的表格.那么如何通过Java应用程序创建Word表格呢?别担心,本文将 ...

  8. Centos7新增静态路由

    文章转载自:https://blog.51cto.com/loong576/2417561 环境说明: 一.临时方式 1. 查看路由和ip [root@centos7 ~]# route -n Ker ...

  9. Traefik2.X 版本 中 URL Rewrite 的使用

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247484594&idx=1&sn=becbe567 ...

  10. logstash另类输出到es

    filebeat配置文件: filebeat.inputs: - type: log enabled: true paths: - /opt/hkd-cloud/hkd-custom/hkd-cust ...