模版介绍笔记:
在前面的章节中,视图函数只是直接返回文本,而在实际生产环境中其实很少这样用,因为实际的页面大多是带有样式的HTML代码,这可以让浏览器渲染出非常漂亮的页面。目前市面上有非常多的模板系统,其中最知名最好用的就是DTL和Jinja2。DTL是Django Template Language三个单词的缩写,也就是Django自带的模板语言。当然也可以配置Django支持Jinja2等其他模板引擎,但是作为Django内置的模板语言,和Django可以达到无缝衔接而不会产生一些不兼容的情况。因此建议大家学习好DTL。
DTL与普通的HTML文件的区别:
DTL模板是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。
渲染模板:
渲染模板有多种方式。这里讲下两种常用的方式。
render_to_string
:找到模板,然后将模板编译后渲染成Python的字符串格式。最后再通过HttpResponse类包装成一个HttpResponse对象返回回去。示例代码如下:
from django.template.loader import render_to_string
from django.http import HttpResponse
def book_detail(request,book_id):
html = render_to_string("detail.html")
return HttpResponse(html)
- 以上方式虽然已经很方便了。但是django还提供了一个更加简便的方式,直接将模板渲染成字符串和包装成HttpResponse对象一步到位完成。示例代码如下:
from django.shortcuts import render
def book_list(request):
return render(request,'list.html')
以上就是通过模板把html渲染并通过浏览器打开
问题:内部原理是怎么知道去王templates文件夹中寻找的呢?
模版查找路径:
在项目的settings.py文件中。有一个TEMPLATES
配置,这个配置包含了模板引擎的配置,模板查找路径的配置,模板上下文的配置等。模板路径可以在两个地方配置。
DIRS
:这是一个列表,在这个列表中可以存放所有的模板路径,以后在视图中使用render或者render_to_string渲染模板的时候,会在这个列表的路径中查找模板。APP_DIRS
:默认为True,这个设置为True后,会在INSTALLED_APPS的安装了的APP下的templates文件加中查找模板。- 查找顺序:比如代码render(‘list.html’)。先会在DIRS这个列表中依次查找路径下有没有这个模板,如果有,就返回。如果DIRS列表中所有的路径都没有找到,那么会先检查当前这个视图所处的app是否已经安装,如果已经安装了,那么就先在当前这个app下的templates文件夹中查找模板,如果没有找到,那么会在其他已经安装了的app中查找。如果所有路径下都没有找到,那么会抛出一个TemplateDoesNotExist的异常。
模版变量笔记:
- 在模版中使用变量,需要将变量放到
{{ 变量 }}
中。 - 如果想要访问对象的属性,那么可以通过
对象.属性名
来进行访问。
以后想要访问class Person(object): def __init__(self,username): self.username = username context = { 'person': p }
person
的username
,那么就是通过person.username
来访问。 - 如果想要访问一个字典的key对应的value,那么只能通过
字典.key
的方式进行访问,不能通过中括号[]
的形式进行访问。
那么以后在模版中访问context = { 'person': { 'username':'zhiliao' } }
username
。就是以下代码person.username
- 因为在访问字典的
key
时候也是使用点.
来访问,因此不能在字典中定义字典本身就有的属性名当作key
,否则字典的那个属性将编程字典中的key了。
以上因为将context = { 'person': { 'username':'zhiliao', 'keys':'abc' } }
keys
作为person
这个字典的key
了。因此以后在模版中访问person.keys
的时候,返回的不是这个字典的所有key,而是对应的值。 - 如果想要访问列表或者元组,那么也是通过
点.
的方式进行访问,不能通过中括号[]
的形式进行访问。这一点和python中是不一样的。示例代码如下:{{ persons.1 }}
if语句笔记:
- 所有的标签都是在
{%%}
之间。 - if标签有闭合标签。就是
{% endif %}
。 - if标签的判断运算符,就跟python中的判断运算符是一样的。
==、!=、<、<=、>、>=、in、not in、is、is not
这些都可以使用。 - 还可以使用
elif
以及else
等标签。
for…in…笔记:
for...in...
类似于Python
中的for...in...
。可以遍历列表、元组、字符串、字典等一切可以遍历的对象。示例代码如下:
{% for person in persons %}
<p>{{ person.name }}</p>
{% endfor %}
如果想要反向遍历,那么在遍历的时候就加上一个reversed
。示例代码如下:
{% for person in persons reversed %}
<p>{{ person.name }}</p>
{% endfor %}
遍历字典的时候,需要使用items
、keys
和values
等方法。在DTL
中,执行一个方法不能使用圆括号的形式。遍历字典示例代码如下:
{% for key,value in person.items %}
<p>key:{{ key }}</p>
<p>value:{{ value }}</p>
{% endfor %}
在for
循环中,DTL
提供了一些变量可供使用。这些变量如下:
forloop.counter
:当前循环的下标。以1作为起始值。forloop.counter0
:当前循环的下标。以0作为起始值。forloop.revcounter
:当前循环的反向下标值。比如列表有5个元素,那么第一次遍历这个属性是等于5,第二次是4,以此类推。并且是以1作为最后一个元素的下标。forloop.revcounter0
:类似于forloop.revcounter。不同的是最后一个元素的下标是从0开始。forloop.first
:是否是第一次遍历。forloop.last
:是否是最后一次遍历。forloop.parentloop
:如果有多个循环嵌套,那么这个属性代表的是上一级的for循环。
** 模板中的for…in…没有continue和break语句,这一点和Python中有很大的不同,一定要记清楚! **
for...in...empty
标签:
这个标签使用跟for...in...
是一样的,只不过是在遍历的对象如果没有元素的情况下,会执行empty
中的内容。示例代码如下:
{% for person in persons %}
<li>{{ person }}</li>
{% empty %}
暂时还没有任何人
{% endfor %}
with标签:
- 在模板中,想要定义变量,可以通过
with
语句来实现。 with
语句有两种使用方式,第一种是with xx=xxx
的形式,第二种是with xxx as xxx
的形式。- 定义的变量只能在with语句块中使用,在with语句块外面使用取不到这个变量。
示例代码如下:
{% with zs=persons.0%}
<p>{{ zs }}</p>
<p>{{ zs }}</p>
{% endwith %}
下面这个因为超过了with语句块,因此不能使用
<p>{{ zs }}</p>
{% with persons.0 as zs %}
<p>{{ zs }}</p>
{% endwith %}
url标签笔记:
url
标签:在模版中,我们经常要写一些url
,比如某个a
标签中需要定义href
属性。当然如果通过硬编码的方式直接将这个url
写死在里面也是可以的。但是这样对于以后项目维护可能不是一件好事。因此建议使用这种反转的方式来实现,类似于django
中的reverse
一样。示例代码如下:
<a href="{% url 'book:list' %}">图书列表页面</a>
如果url
反转的时候需要传递参数,那么可以在后面传递。但是参数分位置参数和关键字参数。位置参数和关键字参数不能同时使用。示例代码如下:
# path部分
path('detail/<book_id>/',views.book_detail,name='detail')
# url反转,使用位置参数
<a href="{% url 'book:detail' 1 %}">图书详情页面</a>
# url反转,使用关键字参数
# book则是 另一个模板 data_list 是路由需要跳转的模板的命名空间名字 detail
<a href="{% url 'book:detail' book_id=1 %}">图书详情页面</a>
url.py需要设置如下代码
path('book_detail/<bookid>', views.book_detail,name="book_detail"),
如果想要在使用url
标签反转的时候要传递查询字符串的参数,那么必须要手动在在后面添加。示例代码如下:
<a href="{% url 'book:book_lgoin' %}?page=1">图书详情页面</a>
urls.py 配置
path('book_lgoin/', views.book_lgoin,name="book_lgoin"),
如果需要传递多个参数,那么通过空格的方式进行分隔。示例代码如下:
<a href="{% url 'book:detail' book_id=1 page=2 %}">图书详情页面</a>
spaceless标签
移除html标签中的空白字符。包括空格、tab键、换行等。示例代码如下:
{% spaceless %}
<p>
<a href="foo/">Foo</a>
</p>
{% endspaceless %}
那么在渲染完成后,会变成以下的代码:
<p><a href="foo/">Foo</a></p>
spaceless只会移除html标签之间的空白字符。而不会移除标签与文本之间的空白字符。看以下代码:
{% spaceless %}
<strong>
Hello
</strong>
{% endspaceless %}
这个将不会移除strong中的空白字符。
autoescape标签
开启和关闭这个标签内元素的自动转义功能。自动转义是可以将一些特殊的字符。比如<转义成html语法能识别的字符,比如<会被转义成<,而>会被自动转义成>。模板中默认是已经开启了自动转义的。autoescape的示例代码如下:
# 传递的上下文信息
context = {
"info":"<a href='www.baidu.com'>百度</a>"
}
# 模板中关闭自动转义
{% autoescape on %}
{{ info }}
{% endautoescape %}
那么就会显示百度的一个超链接。如果把on成off,那么就会显示成一个普通的字符串。示例代码如下:
{% autoescape on %}
{{ info }}
{% endautoescape %}
verbatim标签
默认在DTL模板中是会去解析那些特殊字符的。比如{%和%}以及{{等。如果你在某个代码片段中不想使用DTL的解析引擎。那么你可以把这个代码片段放在verbatim标签中。示例代码下:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
以上是常用的 几种标签 如需了解更多 可以在官方查看教程
https://docs.djangoproject.com/en/2.0/ref/templates/builtins/