Django, Пользовательские функции действий в GenericViewSet или Viewset

Я пытаюсь реализовать базовую систему обмена сообщениями. Пользователь может получать непрочитанные / прочитанные / отправленные сообщения. Каждый из этих маршрутов также возвращает разные сериализованные файлы json. Поэтому у меня нет одного сериализатора для всего ViewSet.

Для этого я попытался реализовать ApiView, который не позволяет мне создавать настраиваемые действия. Итак, я попробовал Viewset, viewset никогда не попадает в get_serializer_class (мне это нужно, так как мне нужно возвращать разные сериализованные модели. Поэтому я попробовал GenericViewSet, который, похоже, работает. Но поскольку get_queryset или queryset необходимо реализовать. Я делаю следующее.

Я проверяю действие в

def get_queryset(self):

    if self.action is 'unread':
        return Message.objects.filter(recipient=user,recipient_deleted_at=None,read_at=None)
    elif self.action is 'recieved':
        return Message.objects.filter(recipient=user,recipient_deleted_at=None)
    elif self.action is 'sent':
        return Message.objects.filter(sender=user,recipient_deleted_at=None)

И одно из действий такое

 def unread(self,request):
    user = self.request.user
    message_set=Message.objects.filter(recipient=user,recipient_deleted_at=None,read_at=None)
    serializer = MessageSerializerFlatList(message_set, many=True)
    return Response(serializer.data)

Это отлично работает, но я снова дважды запрашиваю базу данных: один в непрочитанном действии, а также один раз в функции get_queryset. Есть ли способ получить доступ к возвращаемым данным из функции get_queryset, чтобы мне не приходилось повторно запрашивать информацию.

Я имею в виду, что могу взломать набор get_query и просто вернуть None и выполнять свои операции с db в действиях, но это уродливо.

Короче говоря, я многого прошу от этих Viewset / GenericViewset / ApiView, и правильный путь - это наборы представлений на основе функций. Я просто хотел объединить все операции, связанные с обменом сообщениями, в одном классе.


person Evren Bingøl    schedule 03.11.2019    source источник


Ответы (1)


Итак, в основном вместо реализации функции get_queryset я просто устанавливаю

queryset = Message.objects.all()

и в своей функции я применяю фильтр к набору self.queryset. Поскольку эти наборы запросов не оцениваются, пока вы не начнете их использовать, это отлично работает.

def unread(self,request):
    user = self.request.user
    message_set=self.queryset.filter(recipient=user,recipient_deleted_at=None,read_at=None)
    serializer = MessageSerializerFlatList(message_set, many=True)
    return Response(serializer.data)
person Evren Bingøl    schedule 03.11.2019