Django Rest Framework сериализация "многие ко многим" не работает должным образом - PullRequest
0 голосов
/ 19 сентября 2018

Я копался в stackoverflow и не смог найти ничего, связанного с этой ошибкой / ошибкой.

Ну, у меня есть эта модель:


class ChatRoom(models.Model):
    class Meta:
        app_label = 'chatbot'

    group = models.CharField(max_length=255)
    category = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    url = models.URLField()
    online = models.IntegerField(default=0)
    recaptcha_hash = models.TextField(null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    bots = models.ManyToManyField(MarkBot, through='ChatBot')

    def __str__(self):
        return '{0}/{1}/{2}'.format(self.group, self.category, self.name)

Этот сериализатор:


class ChatRoomSerializer(ModelSerializer):
    bots = MarkBotSerializer(read_only=True, many=True, allow_null=True)

    class Meta:
        model = ChatRoom
        fields = ['group', 'category', 'name', 'url',
                  'online', 'recaptcha_hash', 'bots']
        read_only_fields = ['pk', 'created_at', 'updated_at']

Моя средняя модель «многие ко многим» («сквозная»):


class ChatBot(models.Model):
    class Meta:
        app_label = 'chatbot'

    room_token = models.TextField()
    bot = models.ForeignKey(MarkBot, on_delete=models.CASCADE)
    chat_room = models.ForeignKey(ChatRoom, on_delete=models.CASCADE)

Наконец, мой API-интерфейс, который получает данные для клиента:

class ChatRoomsActive(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, *args, **kwargs):
        user = request.user

        try:
            campaign = Campaign.objects.get(user=user, is_active=True)
            chat_rooms = ChatRoom.objects.filter(campaign=campaign)
            rooms = ChatRoomSerializer(
                data=list(chat_rooms.values()),
                many=True
            )

            if rooms.is_valid():
                return Response({
                    'data': rooms.data,
                    'error': None
                })

        except Campaign.DoesNotExist:
            return Response({
                'data': [],
                'error': 'Campanha inválida'
            }, status=status.HTTP_400_BAD_REQUEST)

        except Exception:
            return Response({
                'data': [],
                'error': 'Ocorreu um erro inesperado em sua requisição'
            }, status=status.HTTP_400_BAD_REQUEST)

        return Response({
            'data': [],
            'error': 'Não foi possível obter as salas ativas'
        }, status=status.HTTP_400_BAD_REQUEST)

И во всех моих сериализованных результатах JSON я получаю атрибут «боты», равный «нулю», даже когда к комнате прикреплен бот.

Ожидаемый результат

Список ботов, прикрепленных к этой конкретной комнате, или ноль, если у него их нет.

Заранее спасибо!

1 Ответ

0 голосов
/ 19 сентября 2018

chat_rooms.values(), скорее всего, не имеет связанного bots, и вызов is_valid для сериализации не имеет смысла - я не уверен, что он работает вообще.

rooms = ChatRoomSerializer(
    instance=list(chat_rooms),
    many=True
)

return Response({
    'data': rooms.data,
    'error': None
})
...