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.

Вернуться на верх