django book 2.0 阅读笔记-模板

本文详细介绍了Django模板系统,包括HTML模板的基本结构、变量、模板标签和过滤器的使用。通过实例展示了如何创建Template对象、传递Context数据、使用基本的模板标签如if/else、for以及过滤器如lower。还讲解了从磁盘加载模板、模板继承和include标签的应用,强调了模板继承在构建高效可复用的模板结构中的重要性。
摘要由CSDN通过智能技术生成

HTML模板简介

引言:{{ }}和 {% %},变量相关的用{{}},逻辑相关的用{%%}。

变量:

用两个大括号括起来的文字(例如 {{ person_name }} )称为 变量(variable)。

模板标签:

被大括号和百分号包围的文本(例如 {% if ordered_warranty %} )是 模板标签(template tag) ,即通知模板系统完成某些工作的标签(比如if,for)。

过滤器:

通过管道符(|)来调用过滤器:

{{ship_date|date:”F j, Y” }};#将变量ship_date传递给date过滤器,同时指定参数”F j,Y”

使用模板的基本方式

  1. 使用 django.template 模块中的Template 类实例化Template 对象,构造函数接受一个参数,该参数可以是原始的模板代码字符串,也可以是模板文件路径;
  2. 调用模板对象的render方法,并且传入一套变量context来渲染模板。他将返回一个模板中的变量和标签被context值替换后的字符串。

Django模板系统的基本规则

写模板,创建 Template 对象,创建 Context , 调用 render() 方法。

Template对象的创建

  1. 转到project目录(由 django-admin.py startproject 命令创建),输入命令 python manage.py shell 启动交互界面,(相较于直接使用python命令,它增加了在配置文件.bash_profile中自动设置DJANGO_SETTINGS_MODULE环境变量的功能,告诉Django使用哪个设置文件(即setting.py))
  2. 创建Template文件
from django.template import Template
t = Template('My name is {{ name }}.')

一旦你创建一个 Template 对象,你可以用 context 来传递数据给它,context在Django里表现为 Context 类,在 django.template 模块里。它的构造函数带有一个可选的参数: 字典-映射变量和它们的值。 最后调用 Template 对象 的 render() 方法并传递context来填充模板:

Context对象的数据传递:

1. 用字典传递数据给Context
from django.template import Context, Template
t = Template('My name is {{ name }}.')
c = Context({'name': 'Stephane'})
t.render(c)

或者多个元素的字典:

from django.template import Template, Context
normal = {'name': 'Sally', 'age': '43'}
t = Template('{{ person.name }} is {{ person.age }} years old.')
c = Context({'person': nomal)
t.render(c)
2. 用类实例化对象传递数据给Context
from django.template import Template, Context
class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name, self.last_name = first_name, last_name
t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
c = Context({'person': Person('John', 'Smith')})
t.render(c)

当数据有自带的方法时,也可以在Template实例化时直接调用,但是注意不可以带括号:

from django.template import Template, Context

t1 = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
t1.render(Context({'var': 'hello'}))#当调用字符串本身的方法时,比如str.upper(),此时方法的括号一定要去掉!!!
3. 用列表传递数据给Context
from django.template import Template, Context

t = Template('Item 2 is {{ items.2 }}.')
c = Context({'items': ['apples', 'bananas', 'carrots']})#context为列表,可以访问列表索引
t.render(c)

注意事项:
当模板系统在变量名中遇到a.b形式传递数据时,按照以下顺序尝试进行查找:

  • 字典类型查找 (比如 foo[“bar”] )

  • 属性查找 (比如 foo.bar )

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

  • 列表类型索引查找 (比如 foo[bar] )

查找时遵循短路逻辑:系统使用找到的第一个有效类型。 且a.b形式的句点查找可以多级深度嵌套。 例如 {{person.name.upper}} 会转换成字典类型查找( person[‘name’] ) 然后再进行方法调用( upper() )。

4. Context对象的增添

Context对象可以使用c[‘name’] = 'guanguan’这样的形式来添加条目。

基本的模板标签和过滤器

标签
  • if/else
    {% if %} 标签检查一个变量,如果这个变量为真,系统会显示在 {% if %} 和 {% endif %} 之间的任何内容,注意{% else %} 标签是可选的:
{% if today_is_weekend %}
    <p>Welcome to the weekend!</p>
{% else %}
    <p>Get back to work.</p>
{% endif %}

{% if %} 标签接受 and,or 或者 not 关键字来对多个变量做判断 ,但不允许在同一个标签中同时使用 and 和 or ,且不支持用圆括号来组合比较操作,也没有 {% elif %} 标签。

{% if athlete_list and coach_list %}
    Both athletes and coaches are available.
{% endif %}
  • for
    {% for %} 允许我们在一个序列上迭代。循环语法是 for X in Y
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}

列表反向迭代:

{% for athlete in athlete_list reversed %}
...
{% endfor %}

{% for %} 标签可以嵌套,且支持一个可选的{% empty %} 分句,通过它来定义循环的列表是否为空:

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

该标签不支持continue和break语句;但每个{% for %}循环里有一个仅仅能够在循环中使用的模板变量forloop ,用来表示当前循环的执行次数。第一次循环时 forloop.counter 将会被设置为1。

{% for item in todo_list %}
    <p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}

forloop.counter0: 类似于 forloop.counter ,但从0开始计数;
forloop.revcounter: 表示循环中剩余项的整型变量。 在循环初次执行时被设置为序列中项的总数。 最后一次循环执行中,这个变量将被置1;
forloop.revcounter0: 类似于 forloop.revcounter ,但它以0做为结束索引。 在第一次执行循环时,该变量会被置为序列的项的个数减1;
forloop.first:布尔值,如果该迭代是第一次执行,那么它被置为true;
forloop.last: 布尔值;在最后一次执行循环时被置为True;
forloop.parentloop: 指向当前循环的上一级循环的 forloop 对象的引用。

  • ifequal/ifnotequal
    {% ifequal %} 标签比较两个值,当他们相等时,显示在 {% ifequal %} 和 {% endifequal %} 之中所有的值。
    注意:只有模板变量,字符串,整数和小数可以作为 {% ifequal %} 标签的参数
{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% else %}
    <h1>No News Here</h1>
{% endifequal %}
注释

注释使用 {# #} :注释不能跨越多行
如果要实现多行注释,可以使用{% comment %} 模板标签

{% comment %}
This is a
multi-line comment.
{% endcomment %}
过滤器

模板过滤器是在变量被显示前修改它的值的一个简单方法

{{ name|lower }}

显示的内容是变量 {{ name }} 被过滤器 lower 处理后的结果,它功能是转换文本为小写。
过滤管道可以被套接,既一个过滤器管道的输出又可以作为下一个管道的输入:

{{ my_list|first|upper }}#查找列表的第一个元素并将其转化为大写

有些过滤器有参数。 过滤器的参数跟随冒号之后并且以双引号包含:

{{ bio|truncatewords:"30" }}

一些重要的过滤器

  • addslashes : 添加反斜杠到任何反斜杠、单引号或者双引号前面;
  • date : 按指定的格式字符串参数格式化 date 或者 datetime 对象;
  • length : 返回变量的长度。 对于列表,这个参数将返回列表元素的个数。 对于字符串,这个参数将返回字符串中字符的个数。

提升:从磁盘中加载模板

TEMPLATE设置

Django 提供了一种使用方便且功能强大的 API ,用于从磁盘中加载模板,为了使用该模板加载API,必须将模板的保存位置告诉框架。
首先在项目目录下新建目录templates,用来存放模板。然后打开settings.py配置文件,找到TEMPLATES这项设置,将templates目录的路径添加到 TEMPLATES 的DIRS属性中:

TEMPLATES = [
    {...
    ‘DIRS’ = ['/home/django/mysite/templates'],//不加方括号会产生找不到templates文件的错误
    ...
    }
]

注意:Python 要求单元素元组中必须使用逗号,以此消除与圆括号表达式之间的歧义

修改视图代码

修改代码使其可以一次性地载入某个模板文件,渲染它,然后将此作为 HttpResponse返回。

from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('temp/current_datetime.html')# get_template()方法会自动为你连接已经设置的 TEMPLATES目录和你传入该方法的模板名称参数,temp为子目录。
    html = t.render({'current_date': now})#字典前面没有加Context,因为加了Context之后在我电脑上会发生错误
    return HttpResponse(html)

上述代码可以简化为:

from django.shortcuts import render_to_response
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    return render_to_response('temp/current_datetime.html', {'current_date': now})
内建函数locals()缩减代码量的使用技巧:
def current_datetime(request):
    current_date = datetime.datetime.now()#相比于之前将获得的日期赋予变量now再使用字典将now映射到模板需要的变量名称current_data,我们直接用current_data获取日期(即使用与模板变量相同的名称),再使用locals()来返回一个**所有**局部变量的名称与值映射的字典,代码量大大减少。
    return render_to_response('current_datetime.html', locals())

include模板标签与继承机制

include模板标签

该标签允许在(模板中)包含其它的模板的内容。 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。

{% include 'includes/nav.html' %}
{% include template_name %}
模板继承

模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。

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

  • 创建一个基础模板base.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    {% block content %}{% endblock %}
    {% block footer %}
    <hr>
    <p>Thanks for visiting my site.</p>
    {% endblock %}
</body>
</html>
  • 在子模版current_time.html中使用它:
    由于{% extends %} 对所传入模板名称使用的加载方法和 get_template() 相同。 也就是说,会将模板名称添加到 TEMPLATES的DIRS 设置之后。而我们在设置时并未指定子目录,所以在这里需要加上。
{% extends "./base.html" %}#代表当前temp1目录下的base.html文件(不指定路径是会产生无法找到template的错误)
{% block title %}The current time{% endblock %}

{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}

继承的三层法:

  1. 创建 base.html 模板,在其中定义站点的主要外观感受。 这些都是不常修改甚至从不修改的部分。

  2. 为网站的每个区域创建 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。这些模板对 base.html 进行拓展,并包含区域特定的风格与设计。2

  3. 为每种类型的页面创建独立的模板,例如论坛页面或者图片库。 这些模板拓展相应的区域模板。

注意:

  1. 必须保证{% extends %} 为模板中的第一个模板标记。 否则,模板继承将不起作用。

  2. 一般来说,基础模板中的 {% block %} 标签(钩子)越多越好。 但是子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。

  3. 如果发觉自己在多个模板之间拷贝代码,应该考虑将该代码段放置到父模板的某个 {% block %} 中。

  4. 如果需要访问父模板中的块的内容,使用 {{ block.super }}标签,这一个魔法变量将会表现出父模板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。

  5. 不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。 也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值