Django笔记 模板 标签

本文介绍了如何在网站开发中利用模板系统简化页面布局,并通过自定义标签增强模板的灵活性。详细展示了两种自定义标签的方法及其应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个工程在之前的基础上做改变

这里写图片描述

一、模板 一个网站有很多结构相同的网页 ,使用模板能有效的避免繁琐重复的工作:
1)、在templates文件夹(与xxx.html同层)下新建base文件夹来存放模板

#base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ Title }}</title>
    {% block head_css %}
    {% endblock %}

    {% block head_js %}
    {% endblock %}
</head>
<body>
    {% block header %}
    {% endblock %}

    {% block container %}
    {% endblock %}

    {% block footer %}
    {% endblock %}
    {% block foot_js %}
    {% endblock %}
</body>
</html>
#login.html

{% extends 'base/base.html' %}         #载入模板

{% block container %}        #对应base.html <bady> 中的container位置
    <form method="get" enctype="multipart/form-data">
    {{ lf.as_p }}
    <a href="http://127.0.0.1:8000/register">注册</a> <input type="submit" value="登录">
    </form>
{% endblock %}

二、 自定义标签

当遇到一个模板标签(template tag)时,模板解析器就会把标签包含的内容,以及模板解析器自己作为参数调用一个python函数。 这个函数负责返回一个和当前模板标签内容相对应的节点(Node)的实例。
根据官方文档首先我们要在APP目录下创建templatetags包,在这个包内实现自定义标签。

方法一:

#upper.py

from django import template

register = template.Library()

class UpperNode(template.Node):
    def __init__(self,nodelist):
        self.nodelist = nodelist

    def render(self, context):
        contand = self.nodelist.render(context)
        return contand.upper()

@register.tag
def upper(parser,token):
    nodelist = parser.parse('endupper')
    parser.delete_first_token()
    return UpperNode(nodelist)

'''
@register.tag(name="current_time")
def do_current_time(parser, token):
    # ...

@register.tag
def shout(parser, token):
    # ...
    如果你像在第二个例子中那样忽略 name 参数的话,Django会使用函数名称作为标签名称。
'''
#login.html

{% extends 'base/base.html' %}

{% block container %}
    {% load upper %}   #载入 upper 开始解析
    {% upper %}        #运行 upper
        Willcome  {{ custom_name }}
    {% endupper %}     #停止解析
    ...
    ...
{% endblock %}

这里需要说明的是

每个标签编译函数有两个参数,parser和token。parser是模板解析器对象。 我们在这个例子中是指 解析到 ‘endupper’ 停止 。 token是正在被解析的语句。

nodelist 存放粗出的节点 此处是 ‘Willcome {{ custom_name }}’ , UpperNode函数进行处理,返回大写字符串。

方法二:在templatetags 文件夹下创建 current_time.py

from django import template
import datetime

register = template.Library() #实例化Library()

class CurrentTimeNode(template.Node):
    def __init__(self, format_string):
        self.format_string = str(format_string)

    def render(self, context):
        now = datetime.datetime.now()
        return now.strftime(self.format_string)

def do_current_time(parser, token):
    try:
        # split_contents() knows not to split quoted strings.
        tag_name, format_string = token.split_contents()
    except ValueError:
        msg = '%r tag requires a single argument' % token.split_contents()[0]
        raise template.TemplateSyntaxError(msg)
    return CurrentTimeNode(format_string[1:-1])

register.tag('current_time', do_current_time) #注册标签

这里需要说明的地方很多:

  1. 每个标签编译函数有两个参数,parser和token。parser是模板解析器对象。 我们在这个例子中并不使用它。
    token是正在被解析的语句。
  2. token.contents 是包含有标签原始内容的字符串。 在我们的例子中,它是 ‘current_time “%Y-%m-%d
    %I:%M %p”’ 。
  3. token.split_contents() 方法按空格拆分参数同时保证引号中的字符串不拆分。 应该避免使用
    token.contents.split() (仅使用Python的标准字符串拆分)。
    它不够健壮,因为它只是简单的按照所有空格进行拆分,包括那些引号引起来的字符串中的空格。
  4. 这个函数可以抛出 django.template.TemplateSyntaxError ,这个异常提供所有语法错误的有用信息。
  5. 不要把标签名称硬编码在你的错误信息中,因为这样会把标签名称和你的函数耦合在一起。
    token.split_contents()[0]总是记录标签的名字,就算标签没有任何参数。
  6. 这个函数返回一个 CurrentTimeNode (稍后我们将创建它),它包含了节点需要知道的关于这个标签的全部信息。
    在这个例子中,它只是传递了参数 “%Y-%m-%d %I:%M %p” 。模板标签开头和结尾的引号使用
    format_string[1:-1] 除去。
  7. 模板标签编译函数 必须 返回一个 Node 子类,返回其它值都是错的。
  8. 这两个函数( init() 和 render() )与模板处理中的两步(编译与渲染)直接对应。 这样,初始化函数仅仅需要存储后面要用到的格式字符串,而 render() 函数才做真正的工作。
  9. 与模板过滤器一样,这些渲染函数应该静静地捕获错误,而不是抛出错误。 模板标签只允许在编译的时候抛出错误。
  10. 最后,你需要用你模块的Library 实例注册这个标签。 注册自定义标签与注册自定义过滤器非常类似(如前文所述)。 只需实例化一个 template.Library 实例然后调用它的 tag() 方法。 例如:

    register.tag('current_time', do_current_time)
    tag() 方法需要两个参数:
    
    ×模板标签的名字(字符串)。
    ×编译函数。
    
{% extends 'base/base.html' %}

{% block container %}
    {% load current_time %} #载入 current_time
    <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
    #运行current_time 参数 "%Y-%m-%d %I:%M %p"
    ...
    ...
{% endblock %}

参考:官方文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值