2010-01-17 87 views
1
from django import template 

register = template.Library() 

class_converter = { 
    "textinput":"textinput textInput", 
    "fileinput":"fileinput fileUpload" 
} 

@register.filter#<-------- 
def is_checkbox(field): 
    return field.field.widget.__class__.__name__.lower() == "checkboxinput" 

@register.filter#<-------- 
def with_class(field): 
    class_name = field.field.widget.__class__.__name__.lower() 
    class_name = class_converter.get(class_name, class_name) 
    if "class" in field.field.widget.attrs: 
     field.field.widget.attrs['class'] += " %s" % class_name 
    else: 
     field.field.widget.attrs['class'] = class_name 
    return unicode(field) 

register.filter和register.filter功能是:@我的代碼

def filter(self, name=None, filter_func=None): 
     if name == None and filter_func == None: 
      # @register.filter() 
      return self.filter_function 
     elif filter_func == None: 
      if(callable(name)): 
       # @register.filter 
       return self.filter_function(name) 
      else: 
       # @register.filter('somename') or @register.filter(name='somename') 
       def dec(func): 
        return self.filter(name, func) 
       return dec 
     elif name != None and filter_func != None: 
      # register.filter('somename', somefunc) 
      self.filters[name] = filter_func 
      return filter_func 
     else: 
      raise InvalidTemplateLibrary("Unsupported arguments to Library.filter: (%r, %r)", (name, filter_func)) 

所以

@register.filter 
def a(): 
    pass 

是平等

register.filter(name=None,filter_func=a) 

是?

回答

2

不完全是。使用修飾語法:

@register.filter 
def a(): 
    pass 

是語法糖:

def a(): 
    pass 
a = register.filter(a) 

所以register.filter在這種情況下,將與第一個位置參數,「名」是你的函數被調用。然而,django register.filter函數處理該用法,並且即使過濾器作爲第一個參數發送也會返回正確的結果(請參閱if callable(name)分支)

使裝飾器可以接受多個參數的做法更常見函數被裝飾成爲第一個位置參數(或者是函數工廠/閉包),但我有一種感覺,django這樣做是爲了向後兼容。其實我隱約記得它過去不是裝飾器,然後在後來的django版本中成爲裝飾器。

0

不。簡單的裝飾器將它們裝飾的函數作爲參數,並返回一個新函數。

a = register.filter(a)