【问题标题】:Django global filterDjango 全局过滤器
【发布时间】:2019-06-11 22:06:09
【问题描述】:

有没有办法全局过滤 Django 模型?我们需要在一个地方设置一个过滤器,以便将其应用于 Django ORM 生成的所有查询,包括相关对象查找等。示例:

class A(Model):
    n = IntegerField()

class B(Model):
    a = ForeignKey(A)

我们想在 A 上设置一个全局过滤器 id__gte=10(为了简单起见是静态的)。然后在进行相关查询时也必须自动应用过滤器,例如

B.objects.filter(a__n=123)  # this code cannot be modified

应该以某种方式神奇地扩展为相当于

B.objects.filter(a__n=123, a__id__gte=10)

我们可以更改模型、管理器、查询集,但我们无法更改实际查询对象的代码(大量代码、第三方应用程序、通用 API)。

【问题讨论】:

  • 假设您查询A.objects.all(),您想过滤As 且id 也小于10?
  • 是的,无处不在。
  • 如果你想让它真正全球化......有一个超级简单的方法:A.objects.filter(id__lt=10).delete()
  • 我要过滤,不要删除。

标签: python django filter global


【解决方案1】:

用过滤器在数据库中创建一个视图并创建一个指向该视图的 Django 模型怎么样?

【讨论】:

  • 这正是我们现在正在做的,也是我们想要放弃的。每当过滤器更改时必须重新创建视图有点笨拙,如果能够使用 Python 代码(在动态过滤器的情况下)会很好。
【解决方案2】:

您应该创建一个自定义管理器并修改初始QuerySet。查看the docs

# First, define the Manager subclass.
class DahlBookManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(author='Roald Dahl')

# Then hook it into the Book model explicitly.
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = models.Manager() # The default manager.
    dahl_objects = DahlBookManager() # The Dahl-specific manager.

那么您应该使用您的自定义管理器 (dahl_objects) 而不是 objects,所有查询都将被修改。

或者您可以覆盖 objects 经理本身

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = DahlBookManager() # The Dahl-specific manager

【讨论】:

  • 1) 正如我所写的,我们无法修改进行查询的代码,我们无法将 A.objects.all() 更改为 A.my_objects.all()。 2) 在我的示例中进行相关查询时,它不会被应用。
  • @RadimBlazek 好的,我更新了答案。无论如何,您仍然需要更新模型。
  • 进行相关查询时不考虑manager(甚至默认)。请参阅我原来的问题中的 B.objects.filter(a__n=123) 。如果我定义 A.objects=MyManager(),它会被 B.objects.filter(a__n=123) 忽略。这是问题的核心,如何将其应用到所有地方。
  • 您能举例说明 A 和 B 的经理应该是什么样子吗?
猜你喜欢
  • 2014-09-20
  • 1970-01-01
  • 2017-05-30
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 1970-01-01
相关资源
最近更新 更多