2011-02-02 22 views
2

我知道您不能使用過濾器調用方法,因爲它是基於數據庫執行的。所以我想寫一個自定義過濾器。Django - 調用方法的自定義過濾器

@staticmethod 
    def custom_filter(obj,method_name, arg=False): 
     for i in obj.objects.all(): 
      if getattr(i, method_name)() == arg: 
       yield i 

我能得到這個,如果我叫工作:

MyModel.custom_filter(MyModel,'my_method','myarg') 

但是,我不能鏈條這些結合在一起像普通的過濾器。

我可以做這樣的事情:

@staticmethod 
def custom_double_filter(obj,method1,arg1,method2,arg2): 
    for i in obj.objects.all(): 
     if getattr(i, method1)() == arg1 and getattr(i,method2)()==arg2: 
      yield i 

,但我想它支持的過濾器和任意數量的一些方法都有自己的論據

@staticmethod 
def custom_double_filter(obj,method1,arg1,method2,arg2): 
    for i in obj.objects.all(): 
     if getattr(i, method1)(<may need to pass an argument>) == arg1 and getattr(i,method2)()==arg2: 
      yield i 

編輯:因此,我試圖做一個像這樣的自定義管理器:

class GroupManager(models.Manager): 
    use_for_related_fields = True 

    def custom_filter(self,method_name, arg=False): 
     results = [] 
     for i in self.all(): 
      if getattr(i, method_name)() == arg: 
       results.append(i) 
     return results 

這適用於一個調用custom_filter,但o自從我返回一個列表以來,我無法將這些調用連接在一起。我需要一種方法來傳遞任意數量的參數

回答

5

過濾器並不是您的模型類的一部分。

它們是與Model類關聯的管理器的一部分。默認管理器實例名爲objects

但是,您可以添加花哨的過濾器。

http://docs.djangoproject.com/en/1.2/topics/db/managers/

當你寫你自己的,定製的經理,請務必閱讀本節:http://docs.djangoproject.com/en/1.2/topics/db/managers/#controlling-automatic-manager-types讓你的新經理做一切默認的管理員做,以及新的,花哨的過濾器。

我希望過濾器能夠調用的方法

這是一個有點瘋狂的任何方法或組合,但您也許能夠使它發揮作用。調用「任何方法」意味着您必須準備並將所有必需的參數傳遞給該方法函數。它開始進入太多*arg**kw metaprogramming爲我的口味。

我會建議經理不是「通用的」,但在經理中有特定方法匹配基礎模型。你也不會打電話給他們filter。您將以簡單的方式將它們映射到模型。

我認爲簡單的管理器方法映射到簡單的模型方法是關於你要做的最好的。

此外,你有很好的老式Python列表解析和生成器函數。我們使用這個。

def our_special_filter(some_queryset): 
    for row in some_queryset: 
     if row.aMethod(): yield row 

result= our_special_filter(SomeModel.objects.filter(...)) 

是的。它打破了流暢的API風格。但它非常簡單,效果很好。

+0

這看起來像我可能想放置過濾器的地方。我怎麼會去寫實際的過濾器呢?我希望過濾器能夠調用任何方法或方法的組合 – JPC 2011-02-02 22:12:03