Roshan A Roshan A - 28 days ago 9
Python Question

Django REST group foreign key models

I have models like below.

Menu Model

class Menu(models.Model):

name = models.CharField(max_length=40, unique=True, verbose_name='menu name')


Item Model

class Item(models.Model):
class Meta:
unique_together = ('shop', 'menu',)

shop = models.ForeignKey(Shop)
menu = models.ForeignKey(Menu)

name = models.CharField(max_length=500)
price = models.IntegerField(default=0)


I want to get the menus for the shop id.


Item.objects.filter(shop_id = 1)


How can I group my results by menu name for the shop id 1. ?

Sample.

{
menu: menuname1
items: [ {item1}, {item2}]
},
{
menu: menuname2
items: [ {item1}, {item2}]
}


Thanks..

Answer Source

You can get your desired output with nested serializers as follows:

models

class Item(models.Model):
    class Meta:
        unique_together = ('shop', 'menu',)

    shop = models.ForeignKey(Shop)
    menu = models.ForeignKey(Menu, related_name='items')
    name = models.CharField(max_length=500)
    price = models.IntegerField(default=0)

serializers

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = '__all__'

class MenuSerialzer(serializers.ModelSerializer):
    items = ItemSerializer(many=True, read_only=True)
    class Meta:
        model = Menu
        fields = ('name','items')

views

class MenuList(generics.ListAPIView):
    serializer_class = MenuSerializer

    def get_queryset(self):
        return Menu.objects.filter(item__shop__id = 1)

I am sure you don't want everytime get shop_id = 1 so do this:

class MenuList(generics.ListAPIView):
    def get_queryset(self):
        shop_id = int(self.kwargs['shop_id'])
        return Menu.objects.filter(item__shop__id = 1)

url.py

urlpatterns = [
   url('^menus/(?P<shop_id>[0-9]+)/$', MenuList.as_view()),
]