【发布时间】:2011-01-30 11:19:23
【问题描述】:
我在我的模型中添加了一个“取消”字段,有没有办法将模型默认查询修改为 cancelled=False 之类的东西?无需修改我的所有过滤/排除查询?
【问题讨论】:
标签: python django django-models metaprogramming
我在我的模型中添加了一个“取消”字段,有没有办法将模型默认查询修改为 cancelled=False 之类的东西?无需修改我的所有过滤/排除查询?
【问题讨论】:
标签: python django django-models metaprogramming
您可以使用自定义模型管理器执行此操作,并覆盖 get_queryset 函数以始终过滤 cancelled=False。
class CustomManager(models.Manager):
def get_queryset(self):
return super().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()。
编辑2:
将现代版 django 的方法拼写从 get_query_set 更新为 get_queryset。
【讨论】:
get_query_set 的拼写是从哪里来的。我相信正确的方法名称是get_queryset。
get_query_set 在 1.6 中已弃用并在 1.8 中删除:docs.djangoproject.com/en/1.10/internals/deprecation/…
您可以编写自定义query manager,但我认为这不是正确的方法。这将为过滤器创建一个隐含的隐藏条件,从而使代码不可读。记住 Python 之禅:Explicit is better than implicit。检测需要添加 cancelled=False 的地方,然后添加这个,这就是你应该这样做的方式。
【讨论】:
not_cancelled = CustomManager() 然后使用 MyModel.not_cancelled.all() 有什么隐含意义?