第04章 模板层

概述

在之前的章节中,视图函数只是直接返回文本,而在实际生产环境中其实很少这样用,因为实际的页面大多是带有样式的HTML代码,这可以让浏览器渲染出非常漂亮的页面。目前市面上有非常多的模板系统,其中最知名最好用的就是DTL和Jinja2。DTLDjango Template Language三个单词的缩写,也就是Django自带的模板语言。当然也可以配置Django支持Jinja2等其他模板引擎,但是作为Django内置的模板语言,和Django可以达到无缝衔接而不会产生一些不兼容的情况。因此建议大家学习好DTL。

DTL与HTML的区别

DTL模板是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。

渲染模板

渲染模板有多种方式。这里讲下两种常用的方式。

  1. render_to_string:找到模板,编译后渲染成python的字符串格式。最后再通过HttpResponse类包装成一个HttpResonse对象返回
  2. render:直接将模板渲染成字符串和包装成HttpResponse对象一步到位完成。
  1. # 1. render_to_string
  2. from django.template.loader import render_to_string
  3. from django.http import HttpResponse
  4. def book_detail(request,book_id):
  5. html = render_to_string("detail.html")
  6. return HttpResponse(html)
  7. # 2. render
  8. from django.shortcuts import render
  9. def book_list(request):
  10. return render(request,'list.html')

模板查找路径配置

在项目的settings.py文件中。有一个TEMPLATES配置,这个配置包含了模板引擎的配置,模板查找路径的配置,模板上下文的配置等。模板路径可以在两个地方配置。

  1. DIRS:这是一个列表,在这个列表中可以存放所有的模板路径,以后在视图中使用render或者render_to_string渲染模板的时候,会在这个列表的路径中查找模板。
  2. APP_DIRS:默认为True,这个设置为True后,会在INSTALLED_APPS的安装了的APP下的templates文件加中查找模板。
  3. 查找顺序:比如代码render('list.html')。先会在DIRS这个列表中依次查找路径下有没有这个模板,如果有,就返回。如果DIRS列表中所有的路径都没有找到,那么会先检查当前这个视图所处的app是否已经安装,如果已经安装了,那么就先在当前这个app下的templates文件夹中查找模板,如果没有找到,那么会在其他已经安装了的app中查找。如果所有路径下都没有找到,那么会抛出一个TemplateDoesNotExist的异常。

内置模板标签和过滤器

url

返回与给定视图和可靠参数匹配的绝对路径引用(没有域名的URL)。结果路径中的任何特殊字符都使用iri_to_uri()编码.

  1. {% url 'some-url-name' v1 v2 %}
  2. {% url 'some-url-name' arg1=v1 arg2=v2 %}
  3. {% url 'myapp:view-name' %} # jinja2 语法为 myapp.view-name
  4. {% url 'some-url-name' as the_url %}
  5. {% if the_url %}
  6. <a href="{{ the_url }}">Link to optional stuff</a>
  7. {% endif %}

注意:

  • URLconf所需的所有参数都应该存在。
  • 不要忘记在URL模式中加引号name,否则该值将被解释为上下文变量!

命名空间URL解析策略

当给定一个名称空间的URL(例如'polls:index')来解析时,Django将完全限定的名称分成几部分,然后尝试以下查找:


首先,Django查找匹配的应用程序名称空间(在本例中'polls')。这将产生该应用程序的实例列表。


如果定义了当前的应用程序,Django将查找并返回该实例的URL解析器。当前的应用程序可以用 函数的current_app参数指定[reverse()](https://docs.djangoproject.com/zh-hans/2.0/ref/urlresolvers/#django.urls.reverse)

[url](https://docs.djangoproject.com/zh-hans/2.0/ref/templates/builtins/#std:templatetag-url)模板标签使用当前解决视图在当前应用程序的命名空间 [RequestContext](https://docs.djangoproject.com/zh-hans/2.0/ref/templates/api/#django.template.RequestContext)。您可以通过在[request.current_app](https://docs.djangoproject.com/zh-hans/2.0/ref/request-response/#django.http.HttpRequest.current_app)属性上设置当前应用程序来覆盖此默认值。


如果没有当前的应用程序。Django寻找一个默认的应用程序实例。默认应用程序实例是具有与应用程序名称空间相匹配的实例名称空间实例(在本例中是一个被调用的实例)。polls'polls'


如果没有默认的应用程序实例,Django会选择应用程序的最后一个部署实例,无论它的实例名称是什么。


如果提供的名称空间在步骤1中与应用程序名称空间不匹配,那么Django会尝试直接查找名称空间作为 实例名称空间

如果有嵌套命名空间,则对命名空间的每个部分重复这些步骤,直到只有视图名称未解析。视图名称将被解析为已找到的名称空间中的URL。

自定义标签和过滤器