django中自定义过滤器,自定义标签
django模板中自带了一系列标签,有<if>,<ifequal>,<ifnotequal>,<for>等,但有时也不能满足需求,比方说我要判断一个对象是否在一个集合中,就没有实现这个功能的现成标签。要实现这个功能,有两种方式,一种是自定义过滤器,一种是自定义标签:
自定义过滤器比较简单:
[python]
import datetime
from django import template
from django.template.base import (Node, NodeList, TemplateSyntaxError)
register = template.Library()
@register.filter(name='authorityfilter')
def authorityfilter(value, authority_list):
for authority in authority_list:
if authority == value:
return True
return False
使用场景:用户登录的时候判断当前用户的权限,如果是超级管理员,则可以查看所有用户的信息,并添加用户等,如果只是普通的用户,则只能看到自己的信息:
自定义过滤器引用方式:
[python]
{% load common_tags %}
{% if 'accountsuperuser'|authorityfilter:request.session.authority_list_button %}
<li><a href="{% url accounts_index %}" target="navTab" rel="accountindex" title="用户管理">用户管理</a></li>
{% else %}
<li><a href="{% url accounts_info user.id %}" target="navTab" rel="accountindex" title="用户信息">用户信息</a></li>
{% endif %}
自定义标签比较复杂,在这里学到一种学习方法,因为django框架是开源的,所以安装好后直接可以看到它的源码。我想判断一个对象是否在一个集合中,要定义的这个标签跟django自带的<ifequal>这个标签实现的功能很类似,好了,先把这个<ifequal>这个标签的源码找出来研究一下。<ifequal>标签源码如下:
[python
@register.tag
def ifequal(parser, token):
"""
Outputs the contents of the block if the two arguments equal each other.
Examples::
{% ifequal user.id comment.user_id %}
...
{% endifequal %}
{% ifnotequal user.id comment.user_id %}
...
{% else %}
...
{% endifnotequal %}
"""
return do_ifequal(parser, token, False)
@register.tag
def ifnotequal(parser, token):
"""
Outputs the contents of the block if the two arguments are not equal.
See ifequal.
"""
return do_ifequal(parser, token, True)
def do_ifequal(parser, token, negate):
bits = list(token.split_contents())
if len(bits) != 3:
raise TemplateSyntaxError("%r takes two arguments" % bits[0])
end_tag = 'end' + bits[0]
nodelist_true = parser.parse(('else', end_tag))
token = parser.next_token()
if token.contents == 'else':
nodelist_false = parser.parse((end_tag,))
parser.delete_first_token()
else:
nodelist_false = NodeList()
val1 = parser.compile_filter(bits[1])
val2 = parser.compile_filter(bits[2])
return IfEqualNode(val1, val2, nodelist_true, nodelist_false, negate)
class IfEqualNode(Node):
child_nodelists = ('nodelist_true', 'nodelist_false')
def __init__(self, var1, var2, nodelist_true, nodelist_false, negate):
self.var1, self.var2 = var1, var2
self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
self.negate = negate
def __repr__(self):
return "<IfEqualNode>"
def render(self, context):
val1 = self.var1.resolve(context, True)
val2 = self.var2.resolve(context, True)
if (self.negate and val1 != val2) or (not self.negate and val1 == val2):
return self.nodelist_true.render(context)
return self.nodelist_false.render(context)
改成<ifcontain>标签后,代码如下:
[python]
def iscontain(obj, obj_list):
for tmpobj in obj_list:
if tmpobj == obj:
return True
return False
class IfContainNode(Node):
child_nodelists = ('nodelist_true', 'nodelist_false')
def __init__(self, var1, var2, nodelist_true, nodelist_false, negate):
self.var1, self.var2 = var1, var2
self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
self.negate = negate
def __repr__(self):
return "<IfContainNode>"
def render(self, context):
val1 = self.var1.resolve(context, True)
val2 = self.var2.resolve(context, True)
if (self.negate and not iscontain(val1, val2)) or (not self.negate and iscontain(val1, val2)):
return self.nodelist_true.render(context)
return self.nodelist_false.render(context)
def do_ifcontain(parser, token, negate):
bits = list(token.split_contents())
if len(bits) != 3:
raise TemplateSy
补充:Web开发 , Python ,