news 2026/9/1 15:31:42

【2014-08-18】Django自学笔记:模板

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【2014-08-18】Django自学笔记:模板

[历史归档]本文原发布于 cstriker1407.info 个人博客,内容为历史存档,仅供参考。
发布时间:2014-08-18| 标题:Django自学笔记:模板分类:编程 / web / Django |标签:模板·django


Django自学笔记:模板

    • 备注:
    • 添加模板:
      • 支持模板原理代码:
      • Django加载模板文件:
    • 模板语法:
      • .运算符:
      • if else:
      • and or not:
      • for:
      • forloop:
      • 多层循环:
      • 注释:
    • 简化后的模板加载代码:
    • Include标签:
    • 模板:
      • {% block %}
      • {{block.super}}:
    • 备注:

最近自学了下Django,这里笔记下学习记录。

备注:

1 学习记录中的代码和资料参考自网络教程【 http://djangobook.py3k.cn/2.0/ 】和【 http://www.djangobook.com/en/2.0/ 】,版权归原作者所有。
2 小弟第一次接触到Django,本笔记可能有错误,还请各位路过的大牛们给予指点。
3 由于教程年代比较久远了,而且Django不同版本改动很大,这里作者的学习笔记是基于【python2.7.8 + django1.6.5】实现的。
4 由于时间关系,学习记录里有的地方记得比较乱,以后有时间再整理下吧。

添加模板:

支持模板原理代码:

首先看下Django是如何支持模板的,开启一个新的CMD,然后输入如下命令:

D:\Documents\pythons\HelloDjango>python manage.py shell Python2.7.8(default,Jun302014,16:08:48)[MSC v.150064bit(AMD64)]on win32Type"help","copyright","credits"or"license"formore information.(InteractiveConsole)>>>fromdjangoimporttemplate>>>t=template.Template('My name is {{ name }}.')>>>c=template.Context({'name':'Adrian'})>>>printt.render(c)My nameisAdrian.>>>c=template.Context({'name':'Fred'})>>>printt.render(c)My nameisFred.>>>c=template.Context()>>>printt.render(c)My nameis.

因此可知:
在Python代码中使用Django模板的最基本方式如下:

  1. 创建一个 Template 对象,将模板代码放入一个 string 中作为参数。
  2. 调用模板(template)对象的 render() 方法,把一组变量作为上下文(context)传入。这么做将会把模板(template)展开,将所有变量(variables)和标签(tags)都赋予相应的值,并作为 string 返回。

Django加载模板文件:

由于Django版本间有差异,这里作者使用的是1.6.5版本,这里作者笔记下如何加载模板文件:
首先在HelloDjango文件夹下新建一个文件夹【templates】,目录结构为:
D:\Documents\pythons\HelloDjango\HelloDjango emplates
然后在templates文件夹下新建一个文件【HelloTemplates.html】,内容很简单,Hello Templates,如下图:

然后添加URL解析代码,如下图:

之后有很重要的一个步骤,打开settings.py,在INSTALLED_APPS中加入一行,如下图:

然后刷新下网页,就可以了:

这里笔记下为什么这样放置template:

在看教程时,发现很多人在settings.py里面添加变量TEMPLATE_DIRS来实现tempate的查找,这里我们看下网址【 https://docs.djangoproject.com/en/1.6/ref/settings/#std:setting-TEMPLATE_DIRS 】中,

TEMPLATE_DIRS Default: () (Empty tuple) List of locations of the template source files searched by django.template.loaders.filesystem.Loader, in search order. Note that these paths should use Unix-style forward slashes, even on Windows. See The Django template language.

即该变量表示了如何要查找template的目录,这里我们继续看网址【 https://docs.djangoproject.com/en/1.6/ref/templates/api/#django.template.loaders.filesystem.Loader 】,

class app_directories.Loader Loads templates from Django apps on the filesystem. For each app in INSTALLED_APPS, the loader looks for a templatessubdirectory. If the directory exists, Django looks for templates in there. This means you can store templates with your individual apps. This also makes it easy to distribute Django apps with default templates. For example, for this setting: INSTALLED_APPS = ('myproject.polls', 'myproject.music') ...then get_template('foo.html') will look for foo.html in these directories, in this order: ?/path/to/myproject/polls/templates/ ?/path/to/myproject/music/templates/ ... and will use the one it finds first.

因此可以通过在INSTALLED_APPS中注册新的APP的方法来实现查找,不过这里需要把template文件放到templates文件夹中,这里我们为了简单,就采取这种方式。

模板语法:

.运算符:

通过.运算符可以方便的调用到字典变量:

>>>t=template.Template('{{ person.name }} is {{ person.age }} years old.')>>>c=template.Context({'person':{'name':'Sally','age':'43'}})>>>t.render(c)u'Sally is 43 years old.'>>>

也可以访问类的成员变量:

>>>classPerson(object):...def__init__(self,first_name,last_name):...self.first_name,self.last_name=first_name,last_name;...>>>t=template.Template('Hello, {{ person.first_name }} {{ person.last_name }}.')>>>c=template.Context({'person':Person('John','Smith')})>>>t.render(c)u'Hello, John Smith.'>>>

也可以调用到无参数的方法:

>>>t=template.Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')>>>t.render(template.Context({'var':'hello'}))u'hello -- HELLO -- False'>>>t.render(template.Context({'var':'123'}))u'123 -- 123 -- True'>>>

也可用于访问列表索引:

>>>t=template.Template('Item 2 is {{ items.2 }}.')>>>c=template.Context({'items':['apples','bananas','carrots']})>>>t.render(c)u'Item 2 is carrots.'>>>

句点查找规则可概括为:当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找:

1 字典类型查找 (比如 foo["bar"] ) 2 属性查找 (比如 foo.bar ) 3 方法调用 (比如 foo.bar() ) 4 列表类型索引查找 (比如 foo )

if else:

HelloTemplates.html:

{% if today_is_weekend %}<p>Welcome to the weekend!</p>{% else %}<p>Get back to work.</p>{% endif %}

MyViewControllers.py:

defshowtemplates(request):t=template.loader.get_template('HelloTemplates.html');c=template.Context();c['today_is_weekend']=True;html=t.render(c);returnHttpResponse(html);

and or not:

HelloTemplates.html:

<p>num1:{{num1}};num2:{{num2}};num3:{{num3}};num4:{{num4}};</p>{% if num1 == 1 or num2 == 2 %}<p>num1 = 1 or num2 = 2</p>{% endif %} {% if num1 == 1 and num3 == 3 %}<p>num1 = 1 and num3 = 3</p>{% endif %} {% if not num4 == 4 %}<p>num4 != 4</p>{% endif %}

MyViewControllers.py:

defshowtemplates(request):t=template.loader.get_template('HelloTemplates.html');c=template.Context();c['num1']=1;c['num2']=2;c['num3']=3;c['num4']=5;html=t.render(c);returnHttpResponse(html);

输出:

for:

reversed:使得该列表被反向迭代。
在执行循环之前先检测列表的大小是一个通常的做法,当列表为空时输出一些特别的提示。

HelloTemplates.html:

{% for athlete in athlete_list %} {{ athlete.name }}<br/>{% empty %} There are no athletes. Only computer programmers.<br/>{% endfor %}<p>==</p>{% for athlete in athlete_list reversed %} {{ athlete.name }}<br/>{% endfor %}

MyViewControllers.py:

defshowtemplates(request):t=template.loader.get_template('HelloTemplates.html');c=template.Context();c['athlete_list']=[{'name':'xiaoming'},{'name':'xiaoqiang'},{'name':'xiaoli'}];html=t.render(c);returnHttpResponse(html);

输出:

forloop:

HelloTemplates.html:

{% for athlete in athlete_list %}<p>{{ athlete.name }}</p>forloop.first:{{forloop.first}}<br/>forloop.last :{{forloop.last }}<br/>forloop.counter:{{forloop.counter}}<br/>forloop.counter0 :{{forloop.counter0 }}<br/>forloop.revcounter :{{forloop.revcounter }}<br/>forloop.revcounter0 :{{forloop.revcounter0 }}<br/>{% endfor %}

MyViewControllers.py:

defshowtemplates(request):t=template.loader.get_template('HelloTemplates.html');c=template.Context();c['athlete_list']=[{'name':'xiaoming'},{'name':'xiaoqiang'},{'name':'xiaoli'}];html=t.render(c);returnHttpResponse(html);

输出:

多层循环:

HelloTemplates.html:

{% for country in countries %}<table>{% for city in country.city_list %}<tr><td>Country #{{ forloop.parentloop.counter }}</td><td>City #{{ forloop.counter }}</td><td>{{ city }}</td></tr>{% endfor %}</table>{% endfor %}

MyViewControllers.py:

defshowtemplates(request):t=template.loader.get_template('HelloTemplates.html');c=template.Context();c['countries']=[{'city_list':['beijing','shanghai','nanjing']},{'city_list':['New York','LA']}];html=t.render(c);returnHttpResponse(html);

输出:

注释:

{# This is a comment #} {% comment %} This is a multi-line comment. {% endcomment %}

简化后的模板加载代码:

HelloTemplates.html:

Hello My Blog Is {{myblog}}.

MyViewControllers.py:

fromdjango.shortcutsimportrender;defshowtemplates(request):returnrender(request,'HelloTemplates.html',{'myblog':'http://116.62.110.235/blog/'})

Include标签:

首先新建一个文件夹navs,在里面新建一个html文件:HelloNav.html,内容为:

<p>YOU ARE IN {{navtitle}}</p>

如下图:

HelloTemplates.html:

{% include "navs/HelloNav.html" %}<p>The Content IS:<br/>{{content}}</p>

MyViewControllers.py:

defshowtemplates(request):t=template.loader.get_template('HelloTemplates.html');c=template.Context();c['navtitle']='Hello This Is Title';c['content']='Hello This Is Content';html=t.render(c);returnHttpResponse(html);

输出:

模板:

{% block %}

{% block %}标签告诉模板引擎,子模板可以重载这些部分。 每个{% block %}标签所要做的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。

首先新建一个父模板文件base.html,内容如下:

{{ title }}<h1>This Is Content A</h1>{% block contentA %}<p>Hello This Is The ContentA In base.html.</p>{% endblock %}<h1>This Is Content B</h1>{% block contentB %}<p>Hello This Is The ContentB In base.html.</p>{% endblock %}<h1>This Is Content C</h1>{% block contentC %}{% endblock %}

然后我们修改HelloTemplates.html,让其继承自base.html:

{% extends "base.html" %} {% block contentA %} This Is The ContentA In HelloTemplates.html {% endblock %} {% block contentC %} {{content}} {% endblock %} {% block contentD %} This Is The ContentD In HelloTemplates.html {% endblock %}

MyViewControllers.py:

defshowtemplates(request):t=template.loader.get_template('HelloTemplates.html');c=template.Context();c['title']='Hello This Is Title';c['content']='Hello This Is Content';html=t.render(c);returnHttpResponse(html);

如下图:

各个block之间的关系:

{{block.super}}:

base.html:

{{ title }}<h1>This Is Content A</h1>{% block contentA %}<p>Hello This Is The ContentA In base.html.</p>{% endblock %}

HelloTemplates.html:

{% extends "base.html" %} {% block contentA %} {{ block.super }} This Is The ContentA In HelloTemplates.html {% endblock %}

输出:

备注:

一些有意思的评注:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 15:26:44

基于SpringBoot的毕业设计导师分配系统(源码+lw+部署文档+讲解等)

温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台…

作者头像 李华
网站建设 2026/9/1 15:19:49

Nacos服务实例频繁掉线:系统性排查框架与解决方案

这次我们来看一个微服务开发中非常实际的问题&#xff1a;Nacos 服务实例频繁掉线&#xff0c;排查半天却找不到原因。这不仅是Nacos本身的问题&#xff0c;更是一个涉及网络、配置、客户端、服务端和运维的综合技术挑战。对于依赖Nacos作为注册中心和配置中心的Spring Cloud或…

作者头像 李华
网站建设 2026/9/1 15:19:39

爱普生L系列打印机查询IP地址与联网状态排查指南

爱普生L3351/3353/3356/3558/3556/3553打印机查询IP地址和联网状态&#xff0c;是配置Wi-Fi打印、共享打印和手机打印绕不开的第一步。很多用户遇到“无法连接打印机”或“找不到打印机”的报错&#xff0c;第一反应是驱动或硬件问题&#xff0c;实际上更常见的原因是打印机IP地…

作者头像 李华
网站建设 2026/9/1 15:19:31

Vue2/Vue3中使用hiprint实现可视化打印设计与报表打印的实践

简介&#xff1a;这是一套专为Vue开发者打造的高性能打印解决方案&#xff0c;面向Web应用开发中需实现定制化报表、票据、证书等复杂打印场景的中高级前端工程师。资源提供hiprint在Vue2与Vue3双版本下的完整封装&#xff0c;涵盖可视化设计器、拖拽式元素编辑、多数据源报表设…

作者头像 李华