当前位置:编程学习 > 网站相关 >>

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 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,