Как я могу использовать пользовательский метод списка и пользовательское действие в наборе данных в DRF? - PullRequest
0 голосов
/ 18 декабря 2018

Из приведенного ниже кода видно, что я использую modelviewset, пользовательский метод list и пользовательское действие с именем get_recent_movies.

class MoviesViewSet(LoginRequiredMixin, ModelViewSet):
    authentication_classes = (authentication.SessionAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)

    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,
                       rest_framework.filters.SearchFilter,
                        rest_framework.filters.OrderingFilter)
    filter_class = MovieFilter
    search_fields = {"title", "genre", "country", "language"}
    ordering_fields = ("title", "genre", "country", "language", "release_year", "timestamp")

    def get_queryset(self):
        queryset = Movie.objects.filter(user=self.request.user).select_related()
        return queryset

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        # Check for Datatables and server side processing parameters
        draw = self.request.query_params.get("draw", None)
        start = self.request.query_params.get("start", None)
        length = self.request.query_params.get("length", None)

        if draw and start and length:
            draw = int(draw)
            start = int(start)
            length = int(length)
            queryset = queryset[start:start+length]
            serializer = MovieListSerializer(queryset, many=True)
            result = {"draw": draw,
                      "recordsTotal": total_count,
                      "recordsFiltered": total_count,
                      "data": serializer.data}
            return Response(result)
        else:
            serializer = MovieListSerializer(queryset, many=True)
            return Response(serializer.data)


    @action(methods=["get"], detail=False,
            url_path="recent", url_name="recent")
    def get_recent_movies(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        queryset = queryset.filter(status=1).order_by("-timestamp")[:12]
        serializer = MovieListSerializer(queryset, many=True)
        return Response(serializer.data)

Причина пользовательского listМетод заключается в том, что я использую Datatables и обработку на стороне сервера, поэтому данные должны быть правильно отформатированы.

Я использую get_recent_movies, чтобы получить последние 12 фильмов, просмотренных пользователем.

Проблема в том, что данные из get_recent_movies должны быть отформатированы для таблиц данных при отображении в таблице.Я мог бы повторить метод list в своем настраиваемом действии, но я не хочу этого делать.

Я не уверен, как передать набор запросов из настраиваемого действия в метод list.

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

Вот еще один способ достичь своей цели:

class MoviesViewSet(LoginRequiredMixin, ModelViewSet):
    authentication_classes = (authentication.SessionAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)

    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,
                       rest_framework.filters.SearchFilter,
                        rest_framework.filters.OrderingFilter)
    filter_class = MovieFilter
    search_fields = {"title", "genre", "country", "language"}
    ordering_fields = ("title", "genre", "country", "language", "release_year", "timestamp")

    def get_queryset(self):
        queryset = Movie.objects.filter(user=self.request.user).select_related()

        if self.action == 'get_recent_movies':
             queryset = queryset.filter(status=1).order_by("-timestamp")[:12]

        return queryset


    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        # Check for Datatables and server side processing parameters
        draw = self.request.query_params.get("draw", None)
        start = self.request.query_params.get("start", None)
        length = self.request.query_params.get("length", None)

        if draw and start and length:
            draw = int(draw)
            start = int(start)
            length = int(length)
            queryset = queryset[start:start+length]
            serializer = MovieListSerializer(queryset, many=True)
            result = {"draw": draw,
                      "recordsTotal": total_count,
                      "recordsFiltered": total_count,
                      "data": serializer.data}
            return Response(result)
        else:
            serializer = MovieListSerializer(queryset, many=True)
            return Response(serializer.data)


    @action(methods=["get"], detail=False, url_path="recent", url_name="recent")
    def get_recent_movies(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

Обратите внимание на метод get_queryset.Здесь вы можете контролировать, какие данные вы вводите в свое пользовательское действие.

0 голосов
/ 18 декабря 2018

Попробуйте,

class MoviesViewSet(LoginRequiredMixin, ModelViewSet):
    # your code

    def get_queryset(self):
        queryset = Movie.objects.filter(user=self.request.user).select_related()
        return queryset

    <b>def check_data_tables(self, queryset):
        # Check for Datatables and server side processing parameters
        draw = self.request.query_params.get("draw", None)
        start = self.request.query_params.get("start", None)
        length = self.request.query_params.get("length", None)

        if draw and start and length:
            draw = int(draw)
            start = int(start)
            length = int(length)
            queryset = queryset[start:start + length]
            serializer = MovieListSerializer(queryset, many=True)
            return {"draw": draw,
                    "recordsTotal": total_count,
                    "recordsFiltered": total_count,
                    "data": serializer.data}
        return {}</b>

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        <b>result = self.check_data_tables(queryset)
        if result:
            return Response(result)</b>
        else:
            serializer = MovieListSerializer(queryset, many=True)
            return Response(serializer.data)

    @action(methods=["get"], detail=False, url_path="recent", url_name="recent")
    def get_recent_movies(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        queryset = queryset.filter(status=1).order_by("-timestamp")[:12]
        serializer = MovieListSerializer(queryset, many=True)
        <b>"""
        if some condtion:
            call check_data_tables() method
        """
        if condition:
            result = result = self.check_data_tables(queryset)
            return processed response</b>
        return Response(serializer.data)

Что я здесь сделал?
Я создал метод класса check_data_tables(), которыйобщие для обоих действий, list и get_recent_movies и вызвали эту функцию, используя self

...