【问题标题】:Django - How to override filter on a model?Django - 如何覆盖模型上的过滤器?
【发布时间】:2012-07-21 23:56:44
【问题描述】:

我很好奇是否有最佳实践或推荐的方法来实现这一点?

假设我有一个这样的模型:

class Cat(models.Model):
    field1=models.CharField(...)
    field2=models.CharField(...)
    evil=models.BooleanField(...)

我想要完成的是,我不希望任何视图能够访问邪恶为 True 的 Cat 记录。

我真的需要在每个 Cat.objects.filter 调用中添加 .filter(evil=False),还是有什么方法可以在课堂上做一次,让邪恶的猫永远不会出现在任何地方?

【问题讨论】:

  • 我认为自定义管理器是最好的选择:docs.djangoproject.com/en/dev/topics/db/managers/…
  • 我同意@Jingo。让它成为一个答案,你就有我的投票权。
  • 谢谢Jingo。这看起来很有希望。如果成功了,我会在这里写下我自己的答案。如果其他人有不同的想法,我仍然会很好奇,但我会试一试。
  • @Greg:使用自定义管理器时,请记住第一个管理器成为“默认”,因此应该不过滤,因此您应该定义objects = models.Manager(),然后定义seenoevil = NoEvilCatsManager()跨度>
  • @Jingo,他们太邪恶了,甚至不应该出现在管理员中 :-) 但是这点很好。

标签: django django-models django-orm


【解决方案1】:

好的,自定义管理器可以适应这里。只需查看docs。就像 Chris Pratt 所说,请记住,第一位经理会成为默认经理。

希望这会导致正确的方向。

更新(也许你可以这样做):

from django.db import models

class EvilCategoryManager(models.Manager):
    def get_query_set(self):
        return super(EvilCategoryManager, self).get_query_set().filter(evil=False)

class Cat(models.Model):
    #.... atrributes here
    objects = models.Manager()
    no_evil_cats = EvilCategoryManager()

【讨论】:

  • 谢谢,你的意思是返回 super(EvilCategoryManager...?
  • 你为什么不直接返回super(EvilCategoryManager, self).filter(evil=False)
  • 来自文档:如果您从 models.Manager 继承,您应该覆盖其 get_query_function 以覆盖其基本查询集,但我认为您也可以 return Cat.objects.filter(evil=False) ...
  • 请注意,虽然您应该将未过滤的管理器设为默认(第一个)管理器,但它不需要命名为“对象”。所以你可以有class Cat(models.Model): all_objects = models.Manager(); objects = EvilCategoryManager()
  • 你需要覆盖get_queryset而不是get_query_set
猜你喜欢
  • 1970-01-01
  • 2020-02-26
  • 2012-03-13
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
相关资源
最近更新 更多