不要在CustomManager.get_query_set()中过滤!但是all(),get(),filter(),exclude()呢?

时间:2009-05-17 14:27:33

标签: django

django's manager docs的段落被DO NOT FILTER AWAY ANY RESULTS IN THIS TYPE OF MANAGER SUBCLASS覆盖,但在以下文字中仅提及get_query_set()

是否保存过滤all(),get(),filter(),exclude()?

我想要这样做的原因:我想要自动管理器,因为它让我有能力控制,哪些行发送到模板标签,如b-list: Write better template tags

中所述

这段代码可以吗?

class ArticleMananger(models.Manager):
    def get_query_set(self):
        return super(ArticleMananger, self).get_query_set()
    def all(self): 
        return super(ArticleMananger, self).filter(published=True)   
    def filter(self,  **kwargs):
        return super(ArticleMananger, self).filter(published=True).filter(**kwargs) 
    .... 

编辑:如果有人投票,那么解释原因会很好或公平。这个问题出了什么问题?

3 个答案:

答案 0 :(得分:3)

我认为,这只是一个警告,只是在你的models.Manager子类中没有覆盖方法get_query_set()而没有进一步考虑Django本身使用这个方法,如果这个管理器得到模型的默认(对象)管理器。否则,您可能会遇到难以调试的行为。

尝试将print语句添加到已覆盖的方法中,以查看其他应用(即管理员应用)使用它们的时间和频率。

答案 1 :(得分:1)

基本思想是,如果您更改模型的默认管理器以all()filter()等常用方法检索对象的方式,您最终会遇到您想要检索某个特定对象但不能检索的情况。通常情况下这很难诊断,因为它会在神秘地出现的情况下出现,或者DoesNotExist出现在你没想到它们的例外情况。

只要保持默认管理器可以正常检索所有内容,就可以在同一个类的其他管理器中执行自定义操作。

答案 2 :(得分:-1)

我做了一些测试,并将回答我自己的问题:

不要过滤所有(),......也是!

我刚试了一下。它会破坏管理界面的一部分。从技术角度来看,有可能覆盖/扩展template / admin / apps / *以使用另一个管理器(即通过自己的标签),但我得出结论,它不值得工作。相反,我会将我的标签重写为以下内容:

def render(self, context):
    if hasattr(self.model, 'publicmgr'):
        context[self.varname] = self.model.publicmgr.all().order_by(self.by)[:self.num]
    else:
        context[self.varname] =   self.model._default_manager.all().order_by(self.by)[:self.num]
    return  ''