Django通过parent获取子对象

nzkunb0c  于 2023-03-24  发布在  Go
关注(0)|答案(2)|浏览(113)

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

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

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

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

我可以执行2个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

但是我在想,是不是可以用1 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等其他应用程序的情况下完成此操作,因为我觉得应该有一个简单的查询操作来完成此操作。

qyyhg6bp

qyyhg6bp1#

你可以像在最后的for循环中那样从parent中获取子对象,但你还需要检查parent的子对象是否存在,如下所示:

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的对象

jljoyd4f

jljoyd4f2#

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

相关问题