django Django模板语言详解 |
您所在的位置:网站首页 › 创建对象的语法是什么意思 › django Django模板语言详解 |
Django模板语言详解
阅读: 73026
评论:14
本节将介绍Django模版系统的语法。Django模版语言致力于在性能和简单性上取得平衡。 如果你有过其它编程背景,或者使用过一些在HTML中直接混入程序代码的语言,那么你需要记住,Django的模版系统并不是简单的将Python嵌入到HTML中。 一、模板模版是纯文本文件,可以生成任何基于文本的文件格式,比如HTML,XML,CSV等。 下面是一个小模版,它展示了一些基本的元素。 {% extends "base_generic.html" %} {% block title %}{{ section.title }}{% endblock %} {% block content %} {{ section.title }} {% for story in story_list %} {{ story.headline|upper }} {{ story.tease|truncatewords:"100" }} {% endfor %} {% endblock %} 二、变量变量看起来就像是这样: {{ variable }}。 当模版引擎遇到一个变量,它将从上下文context中获取这个变量的值,然后用值替换掉它本身。 变量的命名包括任何字母数字以及下划线("_")的组合,最重要的是,变量名称中不能有空格或标点符号。 当模版系统渲染变量的时候遇到点("."),它将以这样的顺序查询这个圆点具体代表的功能: 字典查询(Dictionary lookup) 属性或方法查询(Attribute or method lookup) 数字索引查询(Numeric index lookup)如果你使用的变量不存在,模版系统将插入string_if_invalid选项的值,默认设置为''(空字符串)。 注意,像{{ foo.bar }}这种模版表达式中的“bar”,如果在模版上下文中存在,将解释为一个字面意义的字符串而不是使用变量bar的值 。 三、过滤器过滤器看起来是这样的:{{ name | lower }}。使用管道符号(|)来应用过滤器。该过滤器将文本转换成小写。 过滤器可以“链接”。一个过滤器的输出应用于下一个过滤器。例如:{{ text|escape|linebreaks }}就是一个常用的过滤器链,它首先转移文本内容,然后把文本行转成 标签。 一些过滤器带有参数。 过滤器的参数看起来像是这样: {{ bio|truncatewords:30 }}。 这将显示bio变量的前30个词。 过滤器参数包含空格的话,必须用引号包起来。例如,使用逗号和空格去连接一个列表中的元素,你需要使用{{ list|join:", " }}。 Django提供了大约六十个内置的模版过滤器,很多时候你想要的功能,它都已经提供了,经常查看这些过滤器,发现新大陆吧。下面是一些常用的模版过滤器: 1. default为false或者空变量提供默认值,像这样: {{ value|default:"nothing" }} 2. length返回值的长度。它对字符串和列表都起作用。 {{ value|length }}如果value是['a', 'b', 'c', 'd'],那么输出4。 3. filesizeformat格式化为“人类可读”文件大小单位(即'13 KB',4.1 MB','102 bytes'等)。 {{ value|filesizeformat }}如果value是123456789,输出将会是117.7MB。 我们可以创建自定义的模板过滤器和标签,这是最终极的武器。 四、标签标签看起来像是这样的: {% tag %}。 标签比变量复杂得多,有些用于在输出中创建文本,有些用于控制循环或判断逻辑,有些用于加载外部信息到模板中供以后的变量使用。 一些标签需要开始和结束标签(即 {% 标签 %} ... 标签 内容 ... {% ENDTAG %})。 Django自带了大约24个内置的模版标签。下面是一些常用的标签: 1. for循环标签循环对象中每个元素。需要结束标签{% endfor %} 。例如,显示athlete_list中提供的运动员列表: {% for athlete in athlete_list %} {{ athlete.name }} {% endfor %} 2. if,elif和else标签计算一个表达式,并且当表达式的值是“True”时,显示块中的内容。需要{% endif %}结束标签。整体逻辑非常类似Python的if、elif和else,如下所示。: {% if athlete_list %} Number of athletes: {{ athlete_list|length }} {% elif athlete_in_locker_room_list %} Athletes should be out of the locker room soon! {% else %} No athletes. {% endif %}在上面的例子中,如果athlete_list不是空的,运动员的数量将显示为{{ athlete_list|length }}。否则,如果athlete_in_locker_room_list不为空,将显示“Athletes should be out…”。如果两个列表都是空的,将显示“No athletes.” 。 还可以在if标签中使用过滤器和多种运算符: {% if athlete_list|length > 1 %} Team: {% for athlete in athlete_list %} ... {% endfor %} {% else %} Athlete: {{ athlete_list.0.name }} {% endif %}需要注意,大多数模版过滤器都返回字符串类型,所以使用过滤器做整数类型的比较通常是错误的,但length是一个例外。 3. block和extends标签继承和复写模版。类似Python的类继承和重写机制。 五、注释要注释模版中一行的部分内容,使用注释语法:{# #}。 例如,下面的模版将被渲染为'hello': {# greeting #}hello注释可以包含任何模版内的代码,有效的或者无效的都可以。 像这样: {# {% if foo %}bar{% else %} #}以上是单行注释(在{# .... #}中,不允许有新行)。 如果需要注释掉模版中的多行内容,请使用comment标签。 六、模板继承Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承允许你创建一个包含基本“骨架”的父亲模版,它包含站点中的共有元素,并且可以定义能够被子模版覆盖的blocks。 通过下面这个例子,理解模版继承的概念: {% block title %}My amazing site{% endblock %} {% block sidebar %} Home Blog {% endblock %} {% block content %}{% endblock %}这个模版,通常被命名为base.html,它定义了一个可以用于两列排版页面的简单HTML骨架。 “子模版”需要做的是先继承父模板base.html,然后复写、填充,或者说实现其中的blocks。 block是在子模版中可能会被覆盖掉的位置。在上面的例子中,block标签定义了三个可以被子模版内容填充的block,分别是title、content和siderbar。 再看下面的例子,子模版可能看起来是这样的: {% extends "base.html" %} {% block title %}My amazing blog{% endblock %} {% block content %} {% for entry in blog_entries %} {{ entry.title }} {{ entry.body }} {% endfor %} {% endblock %}extends标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先会去加载父模版,也就是“base.html”。 加载过程中,模版引擎将注意到base.html中的三个block标签,并用子模版中的内容来替换这些block。 根据blog_entries的值,最终输出可能看起来是这样的: My amazing blog Home Blog Entry one This is my first entry. Entry two This is my second entry.请注意,上面例子中的子模版并没有定义sidebar block,这种情况下,将使用父模版中的内容。父模版的{% block %}标签中的内容总是被用作默认内容。 Django还支持多级继承!常用方式是类似下面的三级结构: 创建一个base.html模版,用来控制整个站点的主要视觉和体验。 为站点的每一个app,创建一个base_SECTIONNAME.html模版。 例如base_news.html,base_sports.html。这些模版都继承base.html,并且包含了各自特有的样式和设计。 为每一个页面类型,创建独立的模版,例如新闻内容或者博客文章。 这些模版继承对应app的模版。上面的方式可以使代码得到最大程度的复用,并且使得添加内容到共享的内容区域更加简单,例如app范围内的导航条。 下面是使用继承的一些相关说明: 如果在模版中使用{% extends %}标签,它必须是模版中的第一个标签,必须放在文件首行! 在base模版中设置越多的{% block %}标签越好。子模版不必定义全部父模版中的blocks,所以可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。 如果发现你自己在复制大量重复的模版内容,那意味着你应该把重复的内容移动到父模版中的一个{% block %}中。 如果需要获取父模板中的block的内容,可以使用{{ block.super }}变量。如果想要在父block中新增内容而不是完全覆盖它,这将非常有用。使用{{ block.super }} 插入的数据不会被自动转义,因为父模板中的内容已经被转义。 在{% block %}之外创建的变量使用模板标签的as语法,不能在块内使用。 例如,下面的模板不会显示任何内容: {% trans "Title" as title %} {% block content %}{{ title }}{% endblock %}为了更好的可读性,可以给{% endblock %}标签一个取名字,像这样: {% block content %} ... 在大型模版中,这有助于你清楚的看到哪一个{% block %}标签被关闭了。 最后,请注意不能在一个模版中定义多个相同名字的block标签。 七、自动转义HTML当从模版中生成HTML文件时,总会存在各种风险,比如xss代码注入等恶意攻击。比如下面的模版片段: Hello, {{ name }}首先,它看起来像是无害的,用来显示用户的名字,但是设想一下,如果用户像下面这样输入他的名字,会发生什么: alert('hello')使用这个名字的值,模版将会被渲染成这样: Hello, alert('hello')这意味着浏览器会弹出一个JavaScript警报框! 类似的,如果名字包含一个 ' |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |