Django Rest Framework: разбиение на страницы DRYer для пользовательских действий - PullRequest
0 голосов
/ 15 июня 2019

Предположим, мне нужно настроить несколько конечных точек GET, которые выглядят следующим образом objects/past, objects/future.Пример:

@action(detail=False, methods=["GET"], name="Past Objects")
def past(self, request, *args, **kwargs):
    startdate = datetime.datetime.now()
    some_user = UserProfile.objects.get(user__username="someuser")

    queryset = self.queryset.filter(
        other__attribute__profile=some_user,
        creation_date__lte=startdate
        ).order_by("-creation_date")

    page = self.paginate_queryset(queryset)

    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)

    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)

Вышеописанное работает просто отлично.Но есть ли способ избежать части page = ... -> serializer= ...?

Я указал это в моем ModelViewSet:

pagination_class = CustomObjectPagination

Но кажется, что разбиение на страницы автоматически применяется только к методам по умолчанию, таким как get_queryset и не настраиваемые действия.Нужно ли писать этот шаблон каждый раз, когда я указываю настраиваемое действие, такое как past?

page = self.paginate_queryset(queryset)

if page is not None:
    serializer = self.get_serializer(page, many=True)
    return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

Редактировать: Должно ли было быть яснее, что я спрашиваю конкретно, есть ливстроенный способ сделать выше.

1 Ответ

1 голос
/ 15 июня 2019

Я не думаю, что у нас есть какие-либо встроенные средства, чтобы применять нумерацию действий.Но у нас может быть простой декоратор, чтобы сделать это.Убедитесь, что ваше действие возвращает список или QuerySet при использовании этого декоратора.

from functools import wraps
from django.db.models import QuerySet

def paginate(func):

    @wraps(func)
    def inner(self, *args, **kwargs):
        queryset = func(self, *args, **kwargs)
        assert isinstance(queryset, (list, QuerySet)), "apply_pagination expects a List or a QuerySet"

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
    return inner

@paginate
@action(detail=False, methods=["GET"], name="Past Objects")
def past(self, request, *args, **kwargs):
    startdate = datetime.datetime.now()
    some_user = UserProfile.objects.get(user__username="someuser")

    queryset = self.queryset.filter(
        other__attribute__profile=some_user,
        creation_date__lte=startdate
        ).order_by("-creation_date")

    return queryset
...