Django如何通过父对象获取子对象

3

我试图通过父对象访问子对象,因为我想根据对象的类型执行不同的操作。 我手头有以下代码:

#models.py
class A(models.Model):
    ...

class B(A):
    field1 = models.CharField(...)
    ...

class C(A):
    field2 = models.IntegerField(...)

我可以使用两个 for 循环来实现我想要的效果:

for obj in B.objects.all():
    if field1 == 'something':
        do some operation

for obj in C.objects.all():
    if field2 == 5:
        do some other operation

但是我在想,是否可以使用一个 for 循环并通过父级访问子级来实现这个操作呢?

for obj in A.objects.all():
    if obj.b and obj.b.field1 == 'something':
        do some operation
    elif obj.c and obj.c.field2 == 5:
        do some other operation

我认为可能可以使用select_related,但是它只适用于ForeignKey

此外,我希望在不使用其他应用程序(如django-model-utilsdjango-polymorphic)的情况下完成此操作,因为我觉得应该有一个简单的查询操作来完成这个需求。

我有点困惑你的查询,但是有一个类似的问题。如果 obj.b 并且 obj.b.field1 == 'something':该对象没有属性“b”否则,如果 obj.c 并且 obj.c.field2:该对象也没有属性“c” - sqwale
2个回答

5

您可以像在最后的for循环中那样从父对象获取子对象,但您还需要检查父对象是否存在该子对象:

for obj in A.objects.all():
    try:
        if obj.b.field1 == 'something':
            do some operation
    except ObjectDoesNotExist:
        # obj does not have a child of class B

    try:
        if obj.c.field2 == 5:
            do some other operation
    except ObjectDoesNotExist:
        # obj does not have a child of class C

您也可以使用Q对象将其组合为单个查询:

A.objects.filter(Q(b__isnull=False, b__field1='something') | Q(c__isnull=False, c__field2=5))

这将返回A类的对象。


0
也许这对某些人会有用。 hasattr 将返回正确子实例的 True,否则返回 False。请注意,hasattr 参数中的类名应为小写。
for obj in A.objects.all():
    if obj.hasattr('b'):
       # do something specific to b
    if obj.hasattr('c'):
       # do something specific to c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接