Django получает дочерний объект через parent - PullRequest
0 голосов
/ 13 марта 2019

Я пытался получить доступ к дочернему объекту через родительский объект, поскольку я хочу выполнять различные операции в зависимости от типа объекта.Что у меня есть:

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

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

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

Я мог бы выполнить 2 для циклов и выполнить то, что я хочу:

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 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.

* 1014Более того, я надеялся сделать это без использования дополнительных приложений, таких как django-model-utils или django-polymorphic , потому что я чувствую, что должна быть простая операция запросасделать это.

1 Ответ

2 голосов
/ 13 марта 2019

Вы можете получить дочерний объект от parent, как вы это делали в последнем цикле for, но вам также нужно проверить, существует ли дочерний объект для 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

...