Skip to content
Advertisement

How do I access a model’s nested one-to-many relations?

I have three models as shown below:

class Restaurant(models.Model):
    name = models.CharField(max_length=200)
    address = models.CharField(max_length=200)
    category = models.CharField(max_length=100, blank=True, null=True)

class MenuCategory(models.Model):
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
    name = models.CharField(max_length=200)


class MenuItem(models.Model):
    menu_category = models.ForeignKey(MenuCategory, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=6, decimal_places=2)

A restaurant has many menu categories, which has many menu items.

Is this the right way to lay out these relationships? What’s the most efficient way to get ALL the menu items for a given restaurant?

I’m hoping there’s a more effective way than to loop across all menu categories for a given restaurant.

Advertisement

Answer

You can obtain all MenuItems for a given restaurant with:

MenuItem.objects.filter(menu_category__restaurant=my_restaurant)

where my_restaurant is the Restaurant object for which you want to retrieve the MenuItems.

Django will construct a query for this, and the database will perform JOINs, such that it looks like:

SELECT menu_item.*
FROM menu_item
JOIN menu_category
    ON menu_item.menu_category_id = menu_category.id
WHERE menu_category.restaurant_id = my_restaurant_id

Since ForeignKeys add indexes to the table, typically this JOIN is done quite fast.

Advertisement