Django按子类名称过滤基类

Ozg*_*ali 5 python django django-models

我在Django中有以下模型继承结构:

class Parent(models.Model):
    # stuff

class A(Parent):
    # stuff

class B(Parent):
    # stuff

class C(Parent):
    # stuff

and the list goes on.
Run Code Online (Sandbox Code Playgroud)

我正在使用django-model-utils的InheritanceManager来过滤像这样的对象:

Parent.objects.filter(foo=bar).select_subclasses()
Run Code Online (Sandbox Code Playgroud)

当我想要过滤所有子类时,这很有效.我想要做的是过滤A和B对象,但不过滤C对象.我想用一个像这样的查询来做到这一点

Parent.objects.filter(foo=bar, __class__.__name__=A, __class__.__name__=B).select_subclasses()
Run Code Online (Sandbox Code Playgroud)

是否可以进行这样的过滤操作,如果可能的话怎么做?

Mat*_*kel 3

当然可以在单个查询中完成此操作!

这一切都来自 Django 构建字段来引用父模型和子模型之间关系的方式。每个孩子都有parent-ref某种类型,其中有一个related_name. 这些你都可以查询。

您可能会发现最简单的方法是启动./manage.py shell并导入您的父模型类,然后执行无意义的查询:

Parent.objects.filter(foo='bar')
Run Code Online (Sandbox Code Playgroud)

这应该会向您显示可用于查询的字段:然后您可以了解如何构建查询:

Parent.objects.filter(is_active=True).filter(
    models.Q(a__isnull=False) |
    models.Q(b__isnull=False)
).select_subclasses()
Run Code Online (Sandbox Code Playgroud)

这将执行一个查询,该查询将获取已is_active设置为的 A 的所有对象、B 的所有对象True,并将它们向下转换。

值得指出的是,.select_subclasses()无法检测将包含哪些模型,因此它加入了所有子类。

但是...您可以将值传递给,select_subclasses以便它仅连接(和向下转换)到这些子类:

Parent.objects.filter(is_active=True).filter(
    models.Q(a__isnull=False) |
    models.Q(b__isnull=False)
).select_subclasses('a', 'b')
Run Code Online (Sandbox Code Playgroud)

现在,我们不再加入表“c”到“z”!