Django REST framework group by in nested model
Я новичок в django rest framework.
У меня есть вложенная модель для сохранения заказов ресторана. теперь, когда я отправляю GET запрос, я получаю следующий ответ;
[
{
"menu": {
"id": 1,
"food_name": "food1"
},
"user": {
"id": 49,
"username": "A"
}
},
{
"menu": {
"id": 1,
"food_name": "food1"
},
"user": {
"id": 63,
"username": "B"
}
}
]
но я хочу сгруппировать пользователей с одинаковым меню следующим образом:
[
{
"menu": {
"id": 1,
"food_name": "food1",
"users": {
"1": {
"id": 49,
"username": "A"
},
"2": {
"id": 63,
"username": "B"
}
}
}
}
]
вот мой код:
models.py
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
menu = models.ForeignKey(Menu, on_delete=models.CASCADE)
views.py
class OrderViewSet(viewsets.ModelViewSet):
queryset = Order.objects.all()
serializer_class = OrderSerializer
serilizers.py
class OrderSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer()
menu = MenuSerializer()
class Meta:
model = Order
fields = ['id', 'user', 'menu']
Спасибо
Вы можете вложить User в Menu, если хотите группировать по меню
class OrderSerializer(serializers.HyperlinkedModelSerializer):
menu = MenuSerializer(many=True)
class Meta:
model = Order
fields = ['id', 'menu']
class MenuSerializer(serializers.ModelSerializer):
user = UserSerializer(many=True)
class Meta:
model = Menu
fields = ['id', 'user']
Поскольку ваш вывод предполагает, что вы работаете с меню, я предлагаю вам создать отдельный набор представлений, который работает с меню и возвращает ожидаемый вывод, который вы хотите получить здесь.
Делать ожидаемые результаты в наборе представлений заказа возможно, но сложно оптимизировать с помощью select_related
и prefetch_related
. Но если вы действительно хотите получить это в наборе представлений заказов, то вы можете сделать это с помощью:
class MenuSerializer(serializers.ModelSerializer):
users = serializers.SerializerMethodField()
class Meta:
model = Menu
fields = ['id', 'food_name', 'users']
def get_users(self, obj):
users = User.objects.filter(pk__in=obj.order_set.all().values('user'))
return UserSerializer(users, many=True).data
class OrderSerializer(serializers.HyperlinkedModelSerializer):
menu = MenuSerializer()
class Meta:
model = Order
fields = ['id', 'menu']
Вам также нужно изменить набор запросов представления, если вы хотите получить отдельные результаты, иначе вы получите дубликаты:
class OrderViewSet(viewsets.ModelViewSet):
queryset = Order.objects.all().distinct('menu')
serializer_class = OrderSerializer
Обратите внимание, что это не оптимизировано, и каждая строка в вашей таблице заказов потребует ударов по базе данных только для того, чтобы провести пользователей через меню. distinct('menu')
также работает только на PostgreSQL.