Search code examples
djangodjango-modelsdjango-views

How to display multiple related objects in Django


I have two models that look like this:

class EventDrink(models.Model):
    name = models.CharField(max_length=255)
    drink_active = models.BooleanField()

    def __str__(self):
        return self.name


class EventIngredient(models.Model):
    drink = models.ManyToManyField(EventDrink)
    name = models.CharField(max_length=255)
    url = models.URLField()

    def __str__(self):
        return self.name

I now want to display all drinks with drink_active set to True to display in my view. I also want to display the ingredients related to that drink. I know I can filter on the drinks in my view like this:

drinks = EventDrink.objects.filter(drink_active=1)

But how do I now display the ingredients related to each drink?


Solution

  • You can access the related ones with:

    my_drink.eventingredient_set.all()

    this will trigger a query to fetch the related EventIngredients. If we have to do that for several drinks that is not very efficient. We can use .prefetch_related(…) [Django-doc] to batch all these requests in one additional query, so:

    drinks = EventDrink.objects.filter(drink_active=True).prefetch_related(
        'eventingredient_set'
    )

    We can then for example enumerate over the drinks and their ingredients:

    for drink in drinks:
        print(drink.name)
        for ingredient in drink.eventingredient_set.all():
            print(f' - {ingredient.name}')
        print()