django学习第三天---django模板渲染,过滤器,反向循环 reversed,自定义标签和过滤器,模板继承

网友投稿 256 2022-08-29


django学习第三天---django模板渲染,过滤器,反向循环 reversed,自定义标签和过滤器,模板继承

django模板渲染

模板渲染,模板指的就是html文件,渲染指的就是字符串替换,将模板中的特殊符号替换成相关数据

基本语法

{{ 变量 }} {% 逻辑 %}

变量使用

示例

Views.py文件 def home(request): class A: def __init__(self): self.username = '小白' #如果方法需要再模板中使用,那么不能有其他参数 def xx(self): return '小白xx' info = { 'name' = '小黑' 'hobby' = ['保健','足疗','洗头'], 'num' = 100, 'd1' : {'xx':'oo'}, 'l1': [11,22,{'ss':'kk'}], 'a' : A(), } return render(request,'home.html,info') home.html内容如下 重点:万能的据点号。通过点可以进行数据的索引取值,属性取值,取方法等等

{{ name }}

    {% for i in hobby %}
  • {{ i }}
  • {% endfor %}

{{ num }}

{{ l1.2.ss }}

{{ d1.xx }}

{{ a.username }}

{{ a.xx }} #调用方法时不能加括号,意味着不能传参,也就是后面定义的方法也不能有参数。

urls.py内容 url(r'^home/',views.home)

过滤器

在django的模板语言中,通过使用过滤器来改变变量的显示。

过滤器的语法:{{ value|filter_name:参数 }} 使用过滤器的注意事项 1.过滤器支持'链式'操作。即一个过滤器的输出作为另一个过滤器的输入。 {{ sss|过滤器1:30|过滤器2... }} 2.过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个单词 3.'|'左右没有空格

内置过滤器

常用的内置过滤器示例default

如果一个变量是False或者为空,使用给定的默认值。否则使用变量的值 {{ value|default:'nothing' }} #default后面的默认值记得加引号 如果value没有传值或者值为空或者False的话就显示nothing

length

返回值的长度,作用于字符串和列表,字典等。 {{ value|length }} 返回value的长度,如value=['a','b','c','d']的话,就显示4

filesizeformat

将值格式化为一个'人类可读的'文件尺寸(例如'13kb','4.1MB','102bytes'等等) 例如: {{ value|filesizeformat }} 如果value是123456789,将输出时117.7MB。

slice

切片,如果value='hello world',还有其他可切片的数据类型 {{ value|slice:'2:-1' }} # llo worl

date

格式化,如果value=datetime.datetime.now(),如果不想显示为UTC时间,将django的settings.py配置文件中的TIME_ZONE这一项修改一下,修改为TIME_ZONE = 'Asia/Shanghai' 比如,后台返回的数据为{'value':datetime.datetime.now()} 对上面的数据进行格式化:{{ value|date:'Y-m-d H:i:s' }} #2020-07-14 20:31:41

safe

xxs攻击,全称跨站脚本攻击 Django的模板中在进行模板渲染的时候会对HTML标签和JS语法标签进行自动转义,原因显而易见,这样为了安全,django担心这是用户添加的数据,比如如果有人给你评论的时候写了一段js代码,这个评论已提交,js代码就执行了,这样你是不是可以搞一些事情,写个自动弹框的死循环,那浏览器还能用吗,是不是会一直弹窗,这叫做xss攻击,所以浏览器不让你这么搞,给你转义了,但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话就显示的就是保护HTML标签的源文件。在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器|safe的方式告诉Django这段代码是安全的不必转义。 {'a_tag':'百度'} 渲染 {{ a_tag|safe }} #意思是这个标签是安全的,不让它转义,就显示正常标签

truncatechars

如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列('...')结尾。 参数:截断的字符串 {{ value|truncatechars:9 }} #注意:最后那三个省略号也是9个字符里面的,也就是这个9截断出来的是6个字符加3个省略号。这边要注意下,过滤的长度不能跟你后台数据的字符串长度一致,这样会不显示省略号。只能比你后台数据字符串长度要少。

truncatewords

在一定数量的字后截断字符串,是截多少个单词。 列如: 'hello girl hi baby yue ma' {{ value|truncatewords:3 }}#上面得到的结果是 'hello girl hi ...'

cut

移除value中所有的与给出的变量相同字符串 列子: 'k':' woshi nide baby ' {{ value|cut:' ' }} #移除所有空格 #woshinidebaby

join

使用字符串连接列表,{{ list|join:',' }},就像python中的str.join(list) 'hobby':['洗澡','烫头','推背'] {{ hobby|join:'+' }}

注意:模板渲染在浏览器渲染之前,模板渲染就是字符串替换,替换完成之后,将替换完的整体文件字符串返回给浏览器,浏览器再进行浏览器渲染,展示页面效果

标签

语法

{% 逻辑 %}

for循环标签

示例 #循环列表

#循环列表

    {% for i in hobby %}
  • {{ i }}
  • {% empty %} #当hobby为空或者后台没有给这个数据,那么会显示empty下面的内容

    抱歉,没有查询到相关数据

    {% endfor %}

示例 循环字典

    {% for i in d %} #循环键 {% for i in d.values %} #循环值 {% for k,v in d.items %} #循环键跟值
  • {{ k }}--{{ v }}
  • {% endfor %}

循环计数

    {% for in in l1 %} #{{ forloop }} {% for h in hobby %}
  • {{forloop.parentloop.count }}--{{ forloop.revcounter0 }}--{{ h }}--{{ forloop.last }}
  • {% endfor %} {% endfor %}
forloop的解释 注:循环序号可以通过{{ forloop }}显示,必须在循环内部用forloop.counter 当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能forloop.counter0 当前循环的索引值(从0开始)forloop.revcounter 当前循环的倒序索引值(从1开始)forloop.revcounter0 当前循环的倒序索引值(从0开始)forloop.first 当前循环是不是第一次循环(布尔值)forloop.last 当前循环是不是最后一次循环(布尔值)forloop.parentloop 本层循环的外层循环的需,再通过上面的几个属性来显示外层循环的计数等

反向循环 reversed

'hobby':['a','b','c'] {% for i in hobby reversed %}

  • {{ i }}
  • # c,b,a {% endfor %}

    if标签

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

    {% if num > 100 or num < 0 %} #之间必须隔开不能写一起

    无效

    #不满足这个标签不会生成这个标签 {% elif num > 80 and num < 100 %}

    优秀

    {% else %}

    凑活吧

    {% endif %} 当然也可以只有if和else {% if user_list|length > 5 %} #结合过滤器一起使用

    牛逼克拉斯

    {% else %}

    小米加步枪

    {% endif %} if语句支持and,or,==,>,<,!=,<=,>=,in,not in,is,is not判断,注意条件两边都有空格。

    with标签

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

    列如: 注意等号左右不要加空格 {% with total=business.employees.count %} {{ total }} #只能在with语句体内用,在体外需要使用别名 {% endwith %} 或 {% with business.employees.count as total %} {{ total }} {% endwith %}

    使用标签的注意事项

    1.Django的模板语言不支持连续判断,即不支持以下写法

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

    2.Django的模板语言中属性的优先级大于方法(了解) 注意起名字的时候不要跟方法同名

    def items(request): d = {"a":1,"b":2,"c":3,"items":'100'} return render(request,'xx.html',{'data':d}) 如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的d.items()方法,此时在模板语言中: {{ date.items }} 默认会取d的items key的值

    自定义标签和过滤器

    自定义过滤器

    注意:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag. 1.在app中创建templatetags文件夹(文件夹只能是templatetags) 2.在templatetags文件夹中创建任意.py文件:如:mytag.py 3.在mytag.py文件中写上如下内容 from django import template #先导入这个包 register = template.Library() #制作注册器,名字必须叫register #过滤器最多两个参数 @register.filter #注册过滤器,需要两个参数的 def add(v1,v2): #v1表示管道符前面的,v2表示冒号后面的参数 print(v1,v2) #100 50 return v1+v2 @register.filter #注册过滤器,需要一个参数的 def xxx(v1): #v1表示管道符前面的 print(v1) return 'xxx' @register.simple_tag def atag(v1,v2,v3): #没有参数个数限制,多个参数 print(v1,v2,v3) return v1+v2+v3

    4.使用,在html文件中写上如下内容

    {% load mytag %} #首先通过load来加载一个mytag文件,不一定放在文件的开头,但是一定要放在使用过滤器的前面先进行引用 {{ num|add:50}} #对应2个参数,使用过滤器,和django内置过滤器用法一样,这里生成的是add函数的返回值,#num对应v1,50对应v2 {{ num|xxx }} #对应1个参数 {% atag a b c %}#这个对应没有参数个数限制的,必须是{%%}来包裹使用,显示标签名然后空格写参数,参数之间也是空格分隔的

    模板继承

    将一些页面公共的部分,可以抽离出来单独做成一个html页面,使用这些公用部分的其他html文件,只需要继承一下它就可以了,具体使用流程如下:1.创建公用模板,比如内容如下

    body{ padding:0; margin:0; } {% block css %} .nav{ height:60px; background-color:green; } {% endblock %} .nav a{ color:white; text-decoration:none; } .left-menu{ width:30%; background-color:rgba(0,0,0,0.5); float:left; } .menu .menu-title{ text-align:center; } .main{ float:right; width:65%; height:300px; border:1px solid red; }

    {% block content %} 公共页面 {% endblock %}

    2.将来如果说继承公用模板的html文件中需要修改公用模板中的一些内容,那么需要再公用模板中预留一些钩子,钩子的写法如下

    {% block content %} #block 后面的块名称随便起 公共页面 {% endblock %} #也可以这样写 {% endblock content %} #endblock指定名称

    3.继承公用模板需要再html文件中写入内容:

    {% extends '要继承的html文件名' %} #需要先继承一下公用模板,写法就是extends '公用模板文件名称',注意,必须写在第一行 {% block css %} .nav{ height:60px; background-color:pink; } {% endblock css %} {% block content %}

    首页

    {% endblock content %}

    4.在使用公用模板的其他html文件中,如果需要更改公用模板里面的内容,只需要再html文件中写上相同的钩子,钩子里面写上自定义的内容,写法如下:

    {% block css %} .nav{ height:60px; background-color:pink; } {% endblock %} {% block content %}

    首页

    {% endblock content %}

    注意事项:

    如果你在模板中使用{% extends %}标签,它必须是模板中的第一个标签。其他任何情况下,模板继承都将无法工作,模板渲染的时候django都不知道你在干啥。在base模板中设置越多的{% block %}标签越好,请记住,子模板不必定义全部父模板中的block,所以你可以在大多数block中填充合理的默认内容,然后,只定义你需要的拿一个。多一点钩子总比少一点的好。如果你发现你自己在大量的模板中复制内容,那可能以为着你应该把内容移动到父模板中的一个{% block %}中{{ block.super }}的使用,在子模板中也展示父模板原来钩子中的内容

    {% block content %}

    首页

    {{ block.super }}#在子模板修改父模板内容时,不仅显示修改后的内容,同时也让父模板原有的内容显示 {% endblock %}

    为了更好的可读性,你也可以给你的{% endblock %}标签一个名字。例如:

    {% block content %} ... {% endblock content %} 在大型模板中,这个方法帮你清楚的看到哪一个block标签被关闭了。

    不能在一个模板中定义多个形同名字的block标签

    #两个block都叫content,这种写法不对 {% block content %}

    首页

    {% endblock content %} {% block content %}

    首页

    {{ block.super }} {% endblock %}

    -------------------------------------------

    个性签名:代码过万,键盘敲烂!!!

    如果觉得这篇文章对你有小小的帮助的话,记得“推荐”哦,博主在此感谢!


    版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

    上一篇:django学习第六天---shell指令,单表基于双下划线的模糊查询,distinct注意点,字段的choices属性,url反向解析,orm多表操作创建表
    下一篇:java设计模式七大原则之依赖倒转原则详解
    相关文章

     发表评论

    暂时没有评论,来抢沙发吧~