s_puria
s_puria

Reputation: 407

Django: get related objects of related objects and pass to template

In a Django app I have three models:

class A(models.Model):
     aId =  models.AutoField(primary_key=True)

class B(models.Model):
    bId = models.AutoField(primary_key=True)
    aId = models.ForeignKey(A)

class C(models.Model):
    cId =  models.AutoField(primary_key=True)
    bId = models.ForeignKey(B)

There is a on-to-many relation between A and B, as there is between B and C. And there is a View class with context_data. In the template I need to show and filter Bs, with their Cs. How can I pass All Bs related to an A and All Cs related to those Bs to my template (context)? I tried to get Bs and Cs separately in two arrays, but it seems not to be a good idea because I can not categorize Cs by Bs.

Upvotes: 3

Views: 4649

Answers (2)

Krzysztof Szularz
Krzysztof Szularz

Reputation: 5249

Say you have an instance of A called a.

bs = a.b_set.all()
for b in bs:
    cs = b.c_set.all()

The iteration over the elements might be done in the template itself.

In order to avoid multiple queries you can prefetch related objects.

Upvotes: 4

markus-hinsche
markus-hinsche

Reputation: 1422

So this would be the code for your view. I am not sure from which object(s) are given in the args/kwargs.

from django.views.generic import TemplateView

class YourView(TemplateView):
    template_name = 'yourtemplate.html'

    def get_context_data(self, **kwargs):
        a = kwargs.get('a')
        b = kwargs.get('b')
        ctx = super().get_context_data(**kwargs)

        ctx['all b related to a'] = a.b_set.all()
        ctx['all c related to b'] = b.c_set.all()
        return ctx

If you have to combine querysets, say multiple querysets of cs for each b as @s_puria suggested, you can use the UNION operator https://docs.djangoproject.com/en/1.11/ref/models/querysets/#union

Upvotes: 1

Related Questions