当前位置: 首页 > news >正文

【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 %}

输出:

备注:

一些有意思的评注:

http://www.cnnetsun.cn/news/4355239.html

相关文章:

  • 【three.js教程】Three.js 加载 3D 模型(Loading 3D Models):选对格式,少踩一半坑
  • 基于SpringBoot的毕业设计导师分配系统(源码+lw+部署文档+讲解等)
  • 从“盯屏幕发呆”到“一键生成初稿”:毕夏AI官网正在重新定义毕业论文写作这件事
  • Nacos服务实例频繁掉线:系统性排查框架与解决方案
  • 爱普生L系列打印机查询IP地址与联网状态排查指南
  • Vue2/Vue3中使用hiprint实现可视化打印设计与报表打印的实践
  • 一台设备的代码从头到尾长什么样:从粗浅到通用,新手怎么一步步搭
  • 腾讯音乐2023春招移动客户端笔试复盘与解题思路
  • kkce.com:为什么网站测速要算TCP RTT而非只看TTFB?-快快测
  • Do Large Language Model Agents Exhibit a Survival Instinct? An Empirical Study in a Sugarscape-St...
  • 蔚来数据分析岗笔试复盘:SQL、Python与业务思维全解析
  • Level 4自动驾驶系统设计50——中间件 0
  • SpringBoot与若依框架实战:快速构建图书管理系统全流程指南
  • 学Simulink——UPS系统中双向DC-AC逆变器的并联均流控制仿真
  • MA模型入门:从误差项预测到Python量化实践
  • 燃气灶选购全攻略:看懂定时、防干烧与双气源关键点
  • SageMaker 推理在 Lambda 里卡了 4 秒:删掉两个配置后成本降了 80%
  • 如何5分钟跑通OpenVoice:开源语音克隆完整上手指南
  • 305M 打赢 1014M:pytorch-image-models 官方实测数据里的选型判断
  • 加载项与桌面端的协同诊断 一份联调日志
  • JS 导出 Excel 文件、SheetJS(xlsx)前端导出 Excel
  • 房地产销售中的守盘
  • S/4 HANA ABAP实战:从CDS视图到RAP框架的转型指南
  • AI Agent协同工作流:从通信协议到工程实践
  • 【单片机毕业设计推荐】基于 STM32 的人体健康运动监测终端设计与实现 基于 STM32 的老人跌倒报警与生理参数采集系统设计(023707)
  • 【单片机毕业设计推荐】基于 STM32 或 51 单片机的环境火情监测与短信报警系统设计 基于 STM32 或 51 单片机的室内烟雾温湿度智能监控装置设计(023807)
  • 基于SpringBoot的员工信息管理系统(毕设源码+文档)
  • 2026大专论文降重打分:81%降到5%的实测
  • 加载项与结构化数据 销售台账的实时问答
  • OpenVoice 语音克隆本地部署:10分钟克隆出你的专属声音