how2django[]视图模板

摘要

web的运作方式:

  1. 用户点击链接(路由),向后台发起请求(视图函数),
  2. 后台执行视图函数,返回视图

模板基于参数生成实际的视图。
模板好比是一个类,视图是实际的对象。

模板的应用场景

模板继承的使用场景是,你写好了一个骨架模板后,
可以在子模板引用父模板,并替换或修改父模板的某些部分。

举个例子,我们定义一个显示图书信息的父模板,命名为 base.html:

另外可以先填充测试数据。

模板引擎

在django中自带的是DTL( Django template language)模板引擎,和jinja2类似。
指定和切换模板引擎在settings.py中设置TEMPLATES中的 ‘BACKEND’。

Django2 和 Django3 稍微有点不一样

1
2
3
4
5
6
7
8
9
10
11
12
13
TEMPLATES = [

{

'BACKEND': 'django.template.backends.django.DjangoTemplates',

'DIRS': [],

'APP_DIRS': True,

'OPTIONS': {

},},]

除了可以使用 django 自带的模板系统,还有jinja2系统。
Django是一个强大且全面的大型Web框架,我建议一切都使用django自带的系统,兼容性非常好。

视图函数中的render函数传递一个字典给模板

1
2
render(request, template_name, context=None, content_type=None, status=None, using=None)
render(request, template_name, context=None)

context 字典中元素的键值 “hello” 对应了模板中的变量 ““。

request: 是一个固定参数

template_name: templates中定义的模板文件名,注意路径名。比如:”templates/polls/index.html”, 则参数这样写:”polls/index.html”

context: 要传入文件中用于渲染呈现的数据, 默认是字典格式

content_type: 生成的文档要使用的MIME 类型。默认为DEFAULT_CONTENT_TYPE 设置的值。

status: http的响应代码,默认是200.

using: 用于加载模板使用的模板引擎的名称。默认采用django内置的模板引擎。

context 可以是实名字典也可以是匿名字典。
模板中的变量是字典的key

视图中的字典 只能用点号访问key,不能用中括号访问

1
2
- {{ a.k1  }}
- {{ a['k1']}} 这个就不对

访问列表中的元素 也只能用点号

1
2
- {{a.0}}
- {{a[0]}} 这个就不对

上下文变量查找 仅仅支持点号查找

遍历 Django 模板中复杂数据结构的关键是点号( . )。点号可以访问字典的键、属性、方法或对象的索引。假如我们把一个 Python 字典传给模板。若想通过键访问那个字典中的值,要使用点号。

注意,方法调用中没有括号。此外,不能给方法传递变量(只能调用无需参数的方法)。不允许使用负数索引。

模板系统遇到变量名中的点号时会按照下述顺序尝试查找:

1
2
3
4
5
6
7
字典查找(如 foo["bar"] )

属性查找(如 foo.bar )

方法调用(如 foo.bar() )

列表索引查找(如 foo[2] )

模板系统将使用第一个可用的类型,这是一种短路逻辑。点号查找可以嵌套多层。

一般来说,如果变量不存在,模板系统在变量处插入引擎的 string_if_invalid 配置选项。这个选项的默认值为一个空字符串。

模板中支持的过滤器函数

django模板中默认已经支持了大量常用的函数,
另外也可以自定义拓展更多的函数,建议使用内置的函数,不要自行拓展。
或者使用第三方的模板函数库。自行拓展维护成本有点高,兼容性可能会差。
可以在视图函数中对数据进行清洗,避开在模板中使用复杂函数。

django[]模板过滤器函数汇总,通过过滤器的形式支持简单函数

1
2
- length 计算列表的元素的个数 {{arr|length}}
- stringformat 控制浮点数位数 {{ float_value|stringformat:".2f" }}

load加载导入第三方模板标签或者过滤器

1
2
{% tag %}  使用% 里面的称为标签
{{ var|filter}} 管道后面的称为过滤器
1
{% load packagename %}  加载自定义标签或者过滤器,第三方标签或者过滤器

自定义模板标签或者过滤器

1
你能通过 Python 代码自定义 tags 和 filters 扩展集成模板引擎,通过 {% load %} 标签使其可用。

示例:

include 和 extends 的区别

在正常的做网站时,我们都需要编写很多的html代码,但你会发现,你会重复很多代码,
而每次,这写代码基本上都是复制,然后粘贴,现在有两种解决方法:

1.使用include标记来引入重复的文件的部分 不变
2.使用Django中的模板的继承(extends)特性,可变(block块可以自定义)

extends 查找的位置

所以让我们使用 Django 的模板系统,只要创建一个视图,就可以将页面的设计从代码中分离出来。

情况1:通常写页面都有个模板用来框定头部LOGO页面,左侧导航菜单,只有右部的内容不同。如果不使用模板就大量重复工作。

特别如果头部或者左侧导航需要修改或者添加,所有页面都需要修改。django 通过模板继承解决。

情况2:一个页面如果内容特别多,不可能都一起写同一个页面。比如京东首页内容非常多。如何解决了?django通过include导入其他页面。

extends 的顺序

继承模板和 载入模板的顺序 一致。

settings.py
1
2
TEMPLATE_LOADERS = ['django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader']
  • filesystem.loader 和 template_dir 配合使用

‘django.template.loaders.filesystem.Loader’依赖于’DIRS’的设置,如果’DIRS’是一个空列表的话,他将找不到任何模板

‘django.template.loaders.app_directories.Loader’会自动去app下面的template目录下寻找模板,所以采用这种方法就无需给’DIRS’赋值

如果两个都开启的话
Django会先依据TEMPLATE_LOADERS中最先列出的模板载入方式来查找并载入模板,方式同上,若找不到模板文件则使用列出的第二种方式查找,依次类推,直至找到或找不到。这样的话,Django要么找不到模板,要么会载入最先找到的模板,若在多个不同路径下存在同名的模板文件,最终载入的模板与列出的载入方式的顺序和列出的包含模板的目录的顺序嘻嘻相关。这往往是不明确的,极易造成混淆。

注意事项

%和中括号要紧密靠在一起

管道和前后两个变量也要紧密靠在一起

1
{{  var|filter }}

模板中的url 函数

对于url在template中的映射

对于1中的例子用:

1
{% url ’path.to.some_view’ v1 v2 %}

对于2 中的例子用:

1
{% url ’path.to.some_view’ arg1=v1 arg2=v2 %}
1
{% url 'retro_interactive_mcts' %}

url 第二个参数是 视图函数的同名字符串 需要加引号
除了会帮忙生成正确的url 以后 还会检查是否正确配置了该名字的视图路由

路由url.py

1
url(r'^reactionDB/reaction/rxnid=(?P<rxnid>.+)$', views.reactionbyrxnid, name='reaction_byrxnid'),

视图

1
<a href="{% url 'reaction_byrxnid' 1 %}" class="btn btn-default">Browse</a>

参考

  1. https://docs.djangoproject.com/zh-hans/3.0/topics/templates/
  2. https://www.cnblogs.com/lixiang1013/p/7784523.html
  3. https://michaelyou.github.io/2015/04/15/django%E8%BD%BD%E5%85%A5%E6%A8%A1%E6%9D%BF%E7%9A%84%E9%A1%BA%E5%BA%8F/ good
  4. https://blog.csdn.net/zyz511919766/article/details/18355827
  5. https://blog.csdn.net/wangeen/article/details/40828793