白日依山尽,黄河入海流。欲穷千里目,更上一层楼。 -- 唐·王之涣

django自定义标签学习

前言介绍

Django 默认提供了很多有用的 内置标签和过滤器 ,标签或者过滤器的作用是随处可用 ,它就好像是一个Django 内部命令可以在页面的不同位置使用

对于博客系统来说,最常见的 "最近发布的N条记录""访问量最多的TopN文章" 等都可以使用标签功能是实现。

Django的标签是分类三类

  • 简单标签 simple_tag
  • 应用标签 inclusion_tag
  • 赋值标签 assignment_tag

Django的标签在自定义的时候需要遵循一定的规范

1、标签一定在装载在某个APP下的

2、需要在该APP下创建名字为templatetagsPython包,且名字必须叫这个。既然是包,别忘记了__init__.py 文件

3、在templatetags 包下创建文件名(比如在demo_tags),该文件名不能和Django内置标签名冲突

4、需要在 工程的INSTALLED_APPS 中进行注册

5、最终在template模板中加载 {% load demo_tags%}

自定义简单标签

简单标签通过接受参数,对输入的参数做一些处理,然后返回结果

1
2
3
4
5
6
7
8
9
# blog/templatetags/blog_tags.py

from django import template
# 不管是那种自定义标签,都需要先实现一个 register
register = template.Library()

@register.simple_tag
def say_hello(strs):
return f'Hello {strs}'

使用装饰器,把 say_hello装饰之后注册到template模板中去,这样就可以在template中通过{% load xxx %} 来导入加载

这里作为演示说明,不定义具体的模板HTML页面,我们使用Django内置的Template 函数进行模拟就行

1
2
3
4
5
6
7
8
9
10
11
12
13
(django_blog) [ 22-10-24 18:45 ] [ colinspace ] [~/Documents/python_projects/django_blog] python3 manage.py shell
Python 3.9.6 (default, Jul 16 2021, 13:41:17)
[Clang 12.0.5 (clang-1205.0.22.11)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.template import Template, Context
>>>
>>> t = Template("""
... {% load blog_tags %}
... {% say_hello 'Django blog' %}
... """)
>>> t.render(Context())
'\n\nHello Django blog\n'

另外可以通过@register.simple_tag(name='aliasname') 给简单标签设置别名

自定义引用标签

自定义引用标签可以对其他模板进行渲染,然后将渲染结果输出

这里具体的里面是后面要实现的评论功能,在详情页加载评论框,把 评论框作为一个独立的template定义成一个标签

1
2
3
4
5
6
@register.inclusion_tag('comments/comment_form.html', takes_context=True)
# 如果 takes_context=True ,则自定义引用标签函数的第一个参数必须为context
def show_comment_form(context, post, form=None):
if form is None:
form = CommentForm()
return {'form': form, 'post': post}

comments/comment_form.html 是一个独立的template html 文件,这个而文件中定义了一个 form表单

1
2
3
4
5
6
7
8
9
10
11
12
<!-- comments/templates/comments/comment_form.html -->
<form action="{% url 'comments:comment' post.pk %}" method="post" class="comment-form">
{% csrf_token %}
<div class="row">
<div class="col-md-4">
<label for="{{ form.name.id_for_label }}">{{ form.name.label }}:</label>
{{ form.name }}
{{ form.name.errors }}
</div>
... ...
</div>
</form>

然后在详情页中使用的时候就很方便

1
2
3
4
<!-- 加载标签 -->
{% load comments_extras %}
<!-- 在详情页文章下面 直接按照标签的形式使用 -->
{% show_comment_form post %}

是不是很简单,这样我们就可以累积成自己的标签库,复用到别的项目中去

自定义赋值标签

赋值标签其实就是简单标签 ,只不过在使用的时候,不直接输出结果,而是使用 as 关键字将结果储存在指定的上下文变量中,从而降低了传输上下文的成本

标签还是使用上面的 say_hello ,继续使用 Template 进行演示

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> t = Template("""
... {% load blog_tags %}
... {% say_hello 'Django blog' %}
... """)
>>> t.render(Context())
'\n\nHello Django blog\n'
>>> t2 = Template(""" {% load blog_tags %}
... {% say_hello 'Django blog' as s1 %}
... {{ s1 }}
... """)
>>> t2.render(Context())
' \n\nHello Django blog\n'
>>>

可以看到使用过程中把 结果值赋值给了 s1 然后再其他的位置直接使用 s1 就行。而且可以多次使用

1
2
3
4
5
6
7
8
>>> t3 = Template(""" {% load blog_tags %}
... {% say_hello 'Django blog' as s1 %}
... {{ s1 }}
... <hr>
... 继续使用 {{ s1 }}
... """)
>>> t3.render(Context())
' \n\nHello Django blog\n<hr>\n继续使用 Hello Django blog\n'

如果觉得文章对你有用,请不吝点赞和关注公众号搜索 全栈运维 或者 DailyJobOps

个人博客 http://blog.colinspace.com/

知乎平台 https://www.zhihu.com/people/colin-31-49

CSDN平台 https://blog.csdn.net/eagle5063

简书平台 https://www.jianshu.com/u/6d793fbacc88

作者

Colin

发布于

2022-10-24

许可协议