Ad

Django Get Child Object Through Parent

- 1 answer

I was trying to access the child object, through the parent object, as I want to perform different operations depending on the type of the object. What I have is:

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

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

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

I could perform 2 for loops and accomplish what I want:

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

But I was thinking, is it not possible to do this with 1 for loop and access the child through the parent?

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

I also thought that select_related may do the trick, but it says it works only for ForeignKey.

Moreover, I was hoping to get this done, without using additional apps such as django-model-utils or django-polymorphic, because I feel like there should be a simple query operation to do this.

Ad

Answer

You can get to a child object from parent like you did in the final for loop, but you'd also need to check if the child exists for parent like so:

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

You can also combine this into a single query using Q objects:

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

This would return objects of class A

Ad
source: stackoverflow.com
Ad