Django 系列博客(八)

前言

本篇博客介绍 Django 中的模板层,模板都是Django 使用相关函数渲染后传输给前端在显式的,为了想要渲染出我们想要的数据,需要学习模板语法,相关过滤器、标签。

模板简介

你可能注意到下面的例子返回文本的方式有点特别。当我们使用相关函数来渲染模板的时候,首先是打开了模板文件,然后将需要传入的参数填到文件中在返回给前端。

def current_datetime(request):
now = datetime.datetime.now()
html = '<html><body>It is now %s.</body></html>' % now
return HttpResponse(html)

尽管这很能直观的解释视图层的工作方式,但直接将 HTML 硬编码到你的视图里却不是个好主意。

  • 对页面设计进行的任何改变都必须对python代码进行相应的更改。站点设计的修改往往比底层python代码的修改要频繁的多,因此如何可以在不进行python代码修改的情况下变更设计,那将会方便的多。
  • python代码编写和html设计是两项不同的工作,大多数专业的网站开发环境都会分配不同的部分或者开发人员来完成。设计者和html/css的编码人员不应该被要求去编辑python的代码来完成他们的工作。
  • 程序员编写python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含python又包含html的文件的编辑工作。

基于上述这些原因,将页面的设计和 Python 的代码分离开来会更干净简洁更易维护。可以使用 Django 的模板系统(Templates System)来实现这种模式。

def current_time(req):
import datetime
now = datetime.datetime.now()
html = '<html><body>It is now %s.</body></html>' % now # django模板修改的视图函数
from django.template import Template, Context
now = datetime.datetime.now()
t = '<html><body>It is now %s.</body></html>' % now
c = Context({'current_date': str(now)})
html = t.render(c)
return HttpResponse(html) # 另一种写法
import datetime
now = datetime.datetime.now()
return render(req, 'current_datetime.html', {'current_date': str(now)[:19]})

模板语法终点:

  1. 变量:{{ 变量名 }}

    1. 深度查询,用点语法
    2. 过滤器
  2. 标签:{{ % % }}

模板语法变量

在 Django 模板中遍历复杂数据结构的关键是点语法

views.py

def template_test(request):
name = 'lqz'
li = ['lqz', 1, '18']
dic = {'name': 'lqz', 'age': 18}
ll2 = [
{'name': 'lqz', 'age': 18},
{'name': 'lqz2', 'age': 19},
{'name': 'egon', 'age': 20},
{'name': 'kevin', 'age': 23}
]
ll3=[]
class Person:
def __init__(self, name):
self.name = name def test(self):
print('test函数')
return 11 @classmethod
def test_classmethod(cls):
print('类方法')
return '类方法' @staticmethod
def static_method():
print('静态方法')
return '静态方法' lqz = Person('lqz')
egon = Person('egon')
person_list = [lqz, egon]
bo = True
te = test()
import datetime
now=datetime.datetime.now()
link1='<a href="https://www.baidu.com">点我<a>'
from django.utils import safestring
link=safestring.mark_safe(link1)
# html特殊符号对照表(http://tool.chinaz.com/Tools/htmlchar.aspx) # 这样传到前台不会变成特殊字符,因为django给处理了
dot='&spades;' # return render(request, 'template_index.html', {'name':name,'person_list':person_list})
return render(request, 'template_index.html', locals())

html文件

<p>{{ name }}</p>
<p>{{ li }}</p>
<p>{{ dic }}</p>
<p>{{ lqz }}</p>
<p>{{ person_list }}</p>
<p>{{ bo }}</p>
<p>{{ te }}</p> <hr>
<h3>深度查询句点符</h3>
<p>{{ li.1 }}</p>
<p>{{ dic.name }}</p>
<p>{{ lqz.test }}</p>
<p>{{ lqz.name }}</p>
<p>{{ person_list.0 }}</p>
<p>{{ person_list.1.name }}</p> <hr>
<h3>过滤器</h3>
{#注意:冒号后面不能加空格#}
<p>{{ now | date:"Y-m-d H:i:s" }}</p> {#如果变量为空,设置默认值,空数据,None,变量不存在,都适用#}
<p>{{ name |default:'数据为空' }}</p>
{#计算长度,只有一个参数#}
<p>{{ person_list |length }}</p>
{#计算文件大小#}
<p>{{ 1024 |filesizeformat }}</p> {#字符串切片,前闭后开,前面取到,后面取不到#}
<p>{{ 'hello world lqz' |slice:"2:-1" }}</p>
<p>{{ 'hello world lqz' |slice:"2:5" }}</p> {#截断字符,至少三个起步,因为会有三个省略号(传负数,1,2,3都是三个省略号)#}
<p>{{ '刘清政 world lqz' |truncatechars:"4" }}</p>
{#截断文字,以空格做区分,这个不算省略号#}
<p>{{ '刘清政 是 大帅比 谢谢' |truncatewords:"1" }}</p> <p>{{ link1 }}</p>
<p>{{ link1|safe }}</p>
<p>{{ link }}</p> <p>&spades;</p>
<p>{{ dot }}</p> {#add 可以加负数,传数字字符串都可以#}
<p>{{ "10"|add:"-2" }}</p>
<p>{{ li.1|add:"-2" }}</p>
<p>{{ li.1|add:2 }}</p>
<p>{{ li.1|add:"2" }}</p>
<p>{{ li.1|add:"-2e" }}</p> {#upper#}
<p>{{ name|upper }}</p>
<p>{{ 'LQZ'|lower }}</p>
<hr>
<h3>模版语法之标签</h3>
{#for 循环 循环列表,循环字典,循环列表对象#}
<ui>
{% for foo in dic %}
{{ foo }}
{% endfor %}
{#也可以混用html标签#}
{% for foo in li %}
<ul>foo</ul> {% endfor %}
</ui>
{#表格#}
<table border="1"> {% for foo in ll2 %}
<tr>
<td>{{ foo.name }}</td>
<td>{{ foo.age }}</td>
</tr>
{% endfor %}
</table>
<table border="1">
{#'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}#}
{% for foo in ll2 %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ foo.name }}</td>
<td>{{ foo.age }}</td>
</tr>
{% endfor %} </table> {% for foo in ll5 %}
<p>foo.name</p>
{% empty %}
<p>空的</p>
{% endfor %} <hr>
<h3>if判断</h3>
{% if name %}
<a href="">hi {{ name }}</a>
<a href="">注销</a>
{% else %}
<a href="">请登录</a>
<a href="">注册</a>
{% endif %}
{#还有elif#}
<hr>
<h3>with</h3>
{% with ll2.0.name as n %}
{{ n }}
{% endwith %}
{{ n }} {% load my_tag_filter %} {{ 3|multi_filter:3 }} {#传参必须用空格区分#}
{% multi_tag 3 9 10 %} {#可以跟if连用#}
{% if 3|multi_filter:3 > 9 %}
<p>大于</p>
{% else %}
<p>小于</p>
{% endif %}

注意:点语法也可以用来引用对象的方法(无参数方法)

<h4>字典:{{ dic.name.upper }}</h4>

模板之过滤器

语法:

{{obj|filter__name:param}}  变量名字|过滤器名称:变量

default

如果一个变量是 false 或者为空,使用给定的默认值。否则使用变量的值。

{{ value|default:"nothing" }}

length

返回值得长度。它对字符串和列表都有效。

{{ value|length }}

如果value['a', 'b', 'c', 'd'],那么输出是4。

filesizeformat

将值格式化为一个‘’人类可读的文件尺寸‘’('13KB', '4.1MB'等)。

{{ value|filesizeformat }}

如果 value 是 123456789,输出将会是 117.7 MB。 

date

输出格式化时间

{{ value|date:"Y-m-d" }}

如果value=datetime.datetime.now(),那么结果会是2019-01-10

slice

该方法只能传入一个参数,通常使用引号包裹。

{{ file_size|filesizeformat }}

如果后台的 file_size为1024,那么结果会是1KB

truncatechars

如果字符串字符多于指定的字符数量,那么会被阶段。截断的字符串将以可翻译的省略号序列('...')结束。

参数:要截断的字符数

{{ value|truncatechars:9 }}

safe

Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:

value="<a href="">点击</a>" # 不希望转义的链接
{{ value|safe}} # 添加 safe 过滤器就可以不转义了

其他过滤器

过滤器 描述 示例
upper 以大写方式输出 user.name
add 给value加上一个数值 user.age
addslashes 单引号加上转义号
capfirst 第一个字母大写 'good'|capfirst,返回 good
center 输出指定长度的字符串,把变量居中 'abcd'|center:'50'
cut 删除指定字符串 'You are not a English'|cut:'not'
date 格式化日期
default 如果值不存在,则使用默认值代替 valut|default:'(N/A)'
default_if_none 如果值为None, 则使用默认值代替
dicsort 按某字段排序,变量必须是一个dictionary for moment in moments |dictsort:'id'(百分号加大括号)
dictsortreversed 按某字段倒序排序,变量必须是dictionary
divisibleby 判断是否可以被数字整除 224 | divisibleby:2 返回True
escape 按HTML转义,比如将”<”转换为”&lt”
filesizeformat 增加数字的可读性,转换结果为13KB,89MB,3Bytes等 1024 | filesizeformat 返回1.0KB
first 返回列表的第1个元素,变量必须是一个列表
floatformat 转换为指定精度的小数,默认保留1位小数 3.1415926|floatformat:3 返回3.142四舍五入
get_digit 从个位数开始截取指定位置的数字 12345|get_digit:'1'
join 用指定分隔符连接列表 ['abc','45']|join:'* 返回 abc*45'
length 返回列表中元素的个数或字符串长度
length_is 检查列表,字符串长度是否符合指定的值 hello|length_is:'3'
linebreaks


标签包裹变量

'Hi\n\nDavid'|linebreaks,返回

Hi

David

linebreaksbr
标签代替换行符
linenumbers 为变量中的每一行加上行号
ljust 输出指定长度的字符串,变量左对齐 'ab'|ljust:5 返回'ab '
lower 字符串变小写
make_list 将字符串转换为列表
pluralize 根据数字确定是否输出英文复数符号
random 返回列表的随机一项
removetags 删除字符串中指定的HTML标记 value|removetags:'h1 h2'
rjust 输出指定长度的字符串,变量右对齐
slice 切片操作, 返回列表 [3,9,1]|slice:':2',返回[3,9], 'asdikfjhihgie'|slice:'5',返回'asdik'
slugify 在字符串中留下减号和下划线,其它符号删除,空格用减号替换 '5-2=3and5 2=3'|slugify,返回5-2 3and5-23
stringformat 字符串格式化,语法同python
time 返回日期的时间部分
timesince 以“到现在为止过了多长时间”显示时间变量 结果可能为45days,3hours
timeuntil 以“从现在开始到时间变量”还有多长时间显示时间变量
title 每个单词首字母大写
truncatewords 将字符串转换为省略表达方式 'This is a pen'|truncatewords:2 返回'This is ...'
truncatewords_html 同上,但保留其中的HTML标签 '

This is a pen

'|truncatewords:2,返回

This is ...

urlencode 将字符串中的特殊字符转换为url兼容表达方式 'http://www.aaa.com/foo?a=b&b=c'|urlencode
urlize 将变量字符串中的url由纯文本变为链接
wordcount 返回变量字符串中的单词数
yesno 将布尔变量转换为字符串yes, no 或maybe True|yesno,False|yesno,None|yesno,返回 yes,no,maybe

模板之标签

标签看起来像是这样的:{% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模板中。一些标签需要开始和结束标签(例如{% tag %}...标签 内容... {% endtag %})。

for 标签

遍历每一个元素:

{% for person in person_list %}
<p>{{ person.name }}</p>
{% endfor %}

可以利用{% for obj in list reversed %}反向完成循环。

遍历一个字典:

{% for key,val in dic.items %}
<p>{{ key }}:{{ val }}</p>
{% endfor %}

注:循环序号可以通过``{{ forloop }}显示

forloop.counter            The current iteration of the loop (1-indexed) 当前循环的索引值(从1开始)
forloop.counter0 The current iteration of the loop (0-indexed) 当前循环的索引值(从0开始)
forloop.revcounter The number of iterations from the end of the loop (1-indexed) 当前循环的倒序索引值(从1开始)
forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) 当前循环的倒序索引值(从0开始)
forloop.first True if this is the first time through the loop 当前循环是不是第一次循环(布尔值)
forloop.last True if this is the last time through the loop 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环

for...empty

for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。

{% for person in person_list %}
<p>{{ person.name }}</p> {% empty %}
<p>sorry,no person here</p>
{% endfor %}

if标签

{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

{% if num > 100 or num < 0 %}
<p>无效</p>
{% elif num > 80 and num < 100 %}
<p>优秀</p>
{% else %}
<p>凑活吧</p>
{% endif %}

if语句支持:and、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

with

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的

例如:

{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
不要写成as

cerf_token

{% csrf_token%}

这个标签用于跨站请求伪造保护

自定义标签和过滤器

  1. 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

  2. 在app中创建templatetags模块(模块名只能是templatetags)

  3. 创建任意 .py 文件,如:my_tags.py

from django import template
from django.utils.safestring import mark_safe register = template.Library() #register的名字是固定的,不可改变 @register.filter
def filter_multi(v1,v2):
return v1 * v2
<br>
@register.simple_tag
def simple_tag_multi(v1,v2):
return v1 * v2
<br>
@register.simple_tag
def my_input(id,arg):
result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
return mark_safe(result)
  1. 使用自定义 simple_tag和 fileter 的 html 文件中导入之前创建的 my_tags.py
{% load my_tags %}
  1. 使用simple_tag和filter(如何调用)
{% load xxx %}  

# num=12
{{ num|filter_multi:2 }} #24 {{ num|filter_multi:"[22,333,4444]" }} {% simple_tag_multi 2 5 %} 参数不限,但不能放在if for语句中
{% simple_tag_multi num 5 %}

注意:filter 可以用在 if 等语句后,simple_tag不可以

{% if num|filter_multi:30 > 100 %}
{{ num|filter_multi:30 }}
{% endif %}

Django 系列博客(八)的更多相关文章

  1. Django 系列博客(十六)

    Django 系列博客(十六) 前言 本篇博客介绍 Django 的 forms 组件. 基本属性介绍 创建 forms 类时,主要涉及到字段和插件,字段用于对用户请求数据的验证,插件用于自动生成 h ...

  2. Django 系列博客(十四)

    Django 系列博客(十四) 前言 本篇博客介绍在 html 中使用 ajax 与后台进行数据交互. 什么是 ajax ajax(Asynchronous Javascript And XML)翻译 ...

  3. Django 系列博客(十三)

    Django 系列博客(十三) 前言 本篇博客介绍 Django 中的常用字段和参数. ORM 字段 AutoField int 自增列,必须填入参数 primary_key=True.当 model ...

  4. Django 系列博客(十二)

    Django 系列博客(十二) 前言 本篇博客继续介绍 Django 中的查询,分别为聚合查询和分组查询,以及 F 和 Q 查询. 聚合查询 语法:aggregate(*args, **kwargs) ...

  5. Django 系列博客(十一)

    Django 系列博客(十一) 前言 本篇博客介绍使用 ORM 来进行多表的操作,当然重点在查询方面. 创建表 实例: 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日 ...

  6. Django 系列博客(十)

    Django 系列博客(十) 前言 本篇博客介绍在 Django 中如何对数据库进行增删查改,主要为对单表进行操作. ORM简介 查询数据层次图解:如果操作 mysql,ORM 是在 pymysql ...

  7. Django 系列博客(九)

    Django 系列博客(九) 前言 本篇博客介绍 Django 模板的导入与继承以及导入导入静态文件的几种方式. 模板导入 模板导入 语法:``{% include '模板名称' %} 如下: < ...

  8. Django 系列博客(七)

    Django 系列博客(七) 前言 本篇博客介绍 Django 中的视图层中的相关参数,HttpRequest 对象.HttpResponse 对象.JsonResponse,以及视图层的两种响应方式 ...

  9. Django 系列博客(六)

    Django 系列博客(六) 前言 本篇博客介绍 Django 中的路由控制部分,一个网络请求首先到达的就是路由这部分,经过路由与视图层的映射关系再执行相应的代码逻辑并将结果返回给客户端. Djang ...

随机推荐

  1. NOIP-珠心算

    题目描述 珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术.珠心算训练,既能够开发智力,又能够为日常生活带来很多便利,因而在很多学校得到普及. 某学校的珠心算老师采用一种快速考察珠心算加 ...

  2. 201771010118 马昕璐 《面向对象设计 java》第十七周实验总结

    1.实验目的与要求 (1) 掌握线程同步的概念及实现技术: (2) 线程综合编程练习 2.实验内容和步骤 实验1:测试程序并进行代码注释. 测试程序1: l 在Elipse环境下调试教材651页程序1 ...

  3. 如何设置body高度为浏览器高度

    html{height:100%} body{min-height:100%} 有时我们的页面上内容不多,但设计师要求背景色必须铺满全屏,这时候只需在样式表中加上这行,body就以浏览器的高度显示,超 ...

  4. MySQL之爱之初体验

    写在前言:本篇博客从mysql的安装开始说起,至于什么是数据库以及数据的由来什么的,不在详谈!!! 第一:mysql安装 linux安装:两种方式 1.apt安装 apt install mysql- ...

  5. vue中计算属性computed方法内传参

    vue中computed计算属性无法直接进行传参 如果有传参数的需求比如说做数据筛选功能可以使用闭包函数(也叫匿名函数)实现 例如: 在上篇博客vue安装使用最后的成绩表练习中的过滤功能的实现: &l ...

  6. Java课程之团队开发(NABCD需求分析)

    N.需求 1.学生基本的录入课程功能 2.学生对于空教室使用的需求(自习或者是活动占用) 3.学生对于具体课程的查询需求 A.做法 1.制作出基于安卓的课程查询,录入以及教室查询应用软件 B.好处 1 ...

  7. su;su -;sudo;sudo -i;sudo su;sudo su - 之间的区别

    今天我们来聊聊su;su -;sudo;sudo -i;sudo su;sudo su -他们之间的区别. su :su 在不加任何参数,默认为切换到root用户,但没有转到root用户家目录下,也就 ...

  8. Springboot入门之分布式事务管理

    springboot默认集成事务,只主要在方法上加上@Transactional即可. 分布式事务一种情况是针对多数据源,解决方案这里使用springboot+jta+atomikos来解决 一.po ...

  9. PTA第三次作业

    ---恢复内容开始--- 题目 7-1 计算职工工资 1.设计思路 (1)第一步:观察题意了解各个参数与所需函数在题目中的意义: 第二步:设计算法编写函数,让函数的功能实现题目中所需的功能: 第三步: ...

  10. 坦白说bug

    安卓收藏他发的图片就可以在收藏里看到了哦 苹果直接搜索聊天记录就行了哦(人 •͈ᴗ•͈)۶♡♡比心心