2010-03-22 119 views
20

我已经为模型添加了“取消”字段,有没有办法将模型默认查询修改为像cancel = False这样的东西?而不必修改我所有的过滤/排除查询?在django中修改默认查询集

回答

29

您可以使用自定义模型管理器执行此操作,并覆盖get_queryset函数始终过滤cancel = False。

class CustomManager(models.Manager): 
    def get_queryset(self): 
     return super(CustomManager, self).get_queryset().filter(canceled=False) 

class MyModel(models.Model): 
    # Blah blah 
    objects = CustomManager() 

然后,当调用MyModel.objects.all()时,它将始终排除取消的对象。这里是一篇博文,我发现这个主题很有帮助。 http://www.b-list.org/weblog/2006/aug/18/django-tips-using-properties-models-and-managers/

编辑: 或许有一个自定义的经理更好的方法是将其附加到另一个属性,不是对象等,如:

class MyModel(models.Model): 
    # Blah blah 
    active = CustomManager() 

而在你的意见你的查询看起来像MyModel.active.all()

EDIT2: 对于现代版本的django,更新了从get_query_setget_queryset的拼写方法。

+2

你必须非常非常小心,重写默认管理器就是这样。在这种特殊情况下,一旦项目被取消,您将无法通过filter()/ get()找到它。 – 2010-03-22 18:08:49

+1

同意。我通常会补充这种方法,如果给定pk,则重写get()不使用此过滤器。您可能还想更改管理查询集以返回所有包括取消。但是,如果你很少想在你的查询中取消项目,这可能是一个合理的方法。 – 2010-03-22 18:25:55

+1

嗨,有没有办法修改get_query_set的行为来使用其他参数,即从某处传递,或使用全局变量,如当前登录用户信息?谢谢! – ultrajohn 2012-06-10 21:39:04

4

你可以写自定义query manager,但我不认为这是正确的路要走。这会为过滤器提供隐含的隐藏条件,从而导致代码无法读取。请记住Python的禅宗:Explicit is better than implicit。检测地点,您需要添加取消= False,只需添加此,这是您应该这样做的方式。

+5

我强烈反对。那么,什么是定制管理者?关于'not_cancelled = CustomManager()'然后使用MyModel.not_cancelled.all()隐含了什么? – jonwd7 2010-03-23 04:28:38