31.Django自定义模版

Django自定义模版tag

在使用模版的时候用到{% load static %}等一系列的工具标签,实际上我们也可以自定义这个 标签。

在app目录下面创建一个templatetags目录,必须是这个名字,然后创建一个文件sitetags.py可以根据自己需求取名

1.simple_tag()

sitetags.py

from django import template

register = template.Library()


@register.simple_tag
def slide():
    return '这是自定义标签'

此处省略了,view和url的编写

index.html

<!DOCTYPE html>
# 加载标签 名字就是我们在templatetags下新建的
{% load sitetags %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

# 使用模版,是我们等一的方法
{% slide %}
</body>
</html>

增加参数:
上面我们是写死了结果,这样灵活性严重不足,如果需要修改下文案就无法达到复用的作用了。

修改slide()

@register.simple_tag
def slide(text):
    return text

修改index.html

<!DOCTYPE html>
{% load sitetags %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{% slide '这是带参数的标签'%}
</body>
</html>

刷新浏览器我们将会看到:

这是带参数的标签

获取上下文参数:
上面我们修改成了动态显示内容,那么有时候想要获取整个模版的信息怎么办呢,莫慌,Django已经想到了

再次修改sitetags.py

# 开启上下文,如果设置为True第一个参数必须为context,名字也是固定写法
@register.simple_tag(takes_context=True)
def slide(context, text):
    print(context) # 输出
    return text

可以看到一些请求上下文的封装

[{'True': True, 'False': False, 'None': None}, 
{'csrf_token': <SimpleLazyObject: <function csrf.<locals>._get_val at 0x10f625f28>>, 
'request': <WSGIRequest: GET '/'>, 
'user': <SimpleLazyObject: <function AuthenticationMiddleware.process_request.<locals>.<lambda> at 0x10f625e18>>,
 'perms': <django.contrib.auth.context_processors.PermWrapper object at 0x10f666fd0>, 'messages': <django.contrib.messages.storage.fallback.FallbackStorage object at 0x10f622978>, 
 'DEFAULT_MESSAGE_LEVELS': {'DEBUG': 10, 'INFO': 20, 'SUCCESS': 25, 'WARNING': 30, 'ERROR': 40}}, {}]

给标签取一个名字
在模版中我们使用slide作为标签名称,这是Django的默认行为:
如果没有单独设置名字就取函数名称.

@register.simple_tag(takes_context=True, name='mytag')
def slide(context, text):
    return text

模版中需要使用mytag

{% mytag '这是带参数的标签'%}

安全:
为了放置XSS漏洞,Django默认开启了输出转义,比如里面包含html标签输出就是字符串的html标签。 比如:

123
就是远洋输出。
如果希望不按原样输出可以使用from django.utils.safestring import mark_safe mark_safe()处理,但是务必确保没有安全问题
如果包含html片段使用from django.utils.html import format_html format_html()

2.inclusion_tag()

现在都流行组件化开发,实际上django的模版标签就是类似的东西,我们可以将部分功能封装成 标签模版供其他地方使用

修改sitetags.py

@register.inclusion_tag('messages.html')
def messages():
    return {
        'messages': [
            '今天有雨,请带伞出行',
            '雨天出行注意安全',
            '下雨也不要忘了来第八个部落学习',
        ]
    }

在templates目录下创建messages.html

<ul>
    {% for message in messages %}
        <li>{{ message }}</li>
    {% endfor %}
</ul>


其他带参数数和context用法同simple_tag,不再赘述。

不使用装饰器注册的方式:

from django.template.loader import get_template
t = get_template('messages.html')
register.inclusion_tag(t)(messages)
声明:原创文章,版权所有,转载请注明出处,https://litets.com。