基于Django Rest Framework中的过滤结果的分页

时间:2021-02-16 20:27:40

I have a simple filtering in my get function which needs to be paginated. I tried different ways of solving this issue , but I am not able to figure out what exactly needs to be done. The following is my code

我的get函数中有一个简单的过滤,需要进行分页。我尝试了不同的方法来解决这个问题,但我无法弄清楚到底需要做什么。以下是我的代码

class UserInfoViewSets(viewsets.ViewSet):

    def UserInfo_post(self,request, format=None):
        if request.method == 'POST':
            serializer = UserInfoSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def UserInfo_get(self,request,user_token):  
        if request.method == 'GET':
            queryset = UserInfo.objects.filter(user_token=user_token)
            serializer = UserInfoSerializer(queryset,many=True)

I need to paginate the get results. I dont want to write a customized pagination class, but just set the parameter to limit the no of results per page. I have tried setting the following in the setting.py file

我需要对获得结果进行分页。我不想写一个自定义的分页类,但只需设置参数来限制每页的结果数。我尝试在setting.py文件中设置以下内容

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 2,
}

In my views file , I added ListAPIView

在我的视图文件中,我添加了ListAPIView

class UserInfoListView(generics.ListAPIView):
    model = UserInfo
    serializer_class = UserInfoSerializer
    paginate_by_param = 'limit'

clearly I am overlooking some minor detail. I tried scouting thought the documentation. But it seems to be geared towards people who are well versed with django.

显然我忽略了一些细节。我试着通过侦察思考文档。但它似乎是面向精通django的人。

3 个解决方案

#1


0  

In code below entire viewset is designed GET POST PUT DELETE also your query regarding pagination over filtered query is also handled. Pagination is done using Paginator its a built-in in django

在下面的代码中,整个视图集被设计为GET POST PUT DELETE,您也可以处理有关已过滤查询的分页的查询。分页是使用Paginator完成的,它是django内置的

For docs cover most of the part go to django docs for that. DRF docs can be confusing sometimes but django docs are finely descriptive and easy to implement

对于文档,大部分内容都是为了django docs。 DRF文档有时会令人困惑,但django文档具有良好的描述性且易于实现

views.py

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
@api_view(['GET', 'POST'])
def product_list(request):
    if request.method == 'GET':
        products = Product.objects.all()
        product_make_up = Product.objects.filter(item_category__exact='Make Up')[:3]
        product_skincare = Product.objects.filter(item_category__exact='Skin Care')[:3]
        product_fragrance = Product.objects.filter(item_category__exact='Fragrance')[:3]
        product_personal_care = Product.objects.filter(item_category__exact='Personal Care')[:3]
        product_hair_care = Product.objects.filter(item_category__exact='Hair Care')[:3]
        product_item_category = QuerySetChain(product_make_up,
                                          product_skincare,
                                          product_fragrance,
                                          product_personal_care,
                                          product_hair_care)
        item_cates = request.query_params.get('item_category',None)
        if item_cates is not None:
             product = products.filter(item_category=item_cates)
             paginator = Paginator(product,5)
             page = request.query_params.get('page')
             product = paginator.page(page)
             try:
                 product = paginator.page(page)
             except PageNotAnInteger:
                 product = paginator.page(1)
             except EmptyPage:
                 product = pagintor.page(paginator.num_pages)
                 serializer = ProductSerializer(product, many=True)
    else:
        paginator = Paginator(product_item_category,15)
        page = request.query_params.get('page')
        product_item_category = paginator.page(page)
        try:
            product_item_category = paginator.page(page)
        except PageNotAnInteger:
            product_item_category = paginator.page(1)
        except EmptyPage:
            product_item_category = pagintor.page(paginator.num_pages)
        serializer = ProductSerializer(product_item_category, many=True)    
    return Response(serializer.data)
elif request.method == 'POST':
    serializer = ProductSerializer( data=request.data)
    # data.encode("base64")
    if serializer.is_valid():
        serializer.save()
        res_msg = {'Success_Message' : 'Successful','Success_Code' : 200}
        return Response(res_msg)
    else:
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def product_detail(request, pk):
"""
Get, udpate, or delete a specific task
"""
    try:
        product = Product.objects.get(pk=pk)
    except Product.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = ProductSerializer(product)
        return Response(serializer.data , status=status.HTTP_201_CREATED)

    elif request.method == 'PUT':
        serializer = ProductSerializer(product, data=request.data)
        if serializer.is_valid():
            serializer.save()
        return Response(serializer.data)
        else:
            return Response(
            serilizer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        product.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

#2


0  

That is what I do for pagination, filtering, ordering etc... First you need to pip install django-filter (https://github.com/alex/django-filter)

这就是我为分页,过滤,订购等所做的...首先你需要pip install django-filter(https://github.com/alex/django-filter)

settings.py

REST_FRAMEWORK = {

    . . . 

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'DEFAULT_FILTER_BACKENDS': (
        'rest_framework.filters.DjangoFilterBackend',
    ),
    'PAGE_SIZE': 1000

    . . .

}

views.py

class UserViewSet(viewsets.ModelViewSet):
    lookup_field = 'id'
    queryset = Users.objects.order_by('id')
    serializer_class = AccountSerializer
    filter_backends = (SearchFilter, OrderingFilter)
    search_fields = ('^id', '^first_name', '^last_name', '^email', ^username',)

I am using AngularJS,

我正在使用AngularJS,

function getUserList(limit, pageNumber, search, ordering) {

    var def = $q.defer();
    offset = (pageNumber -1) * limit;
    $http.get(API_URL +
        '?limit=' +limit +
        '&offset=' + offset +
        '&search=' + search +
        '&ordering=' + ordering)

    .success(function(data){
        def.resolve(data);
    })
    .error(function(data){
        def.resolve(data);
    });

    return def.promise;
}

Example query:

http://127.0.0.1:8000/user/?limit=10&offset=0&search=%20&ordering=id

#3


0  

Thanks @umut and @prashant. I am sharing my version plainly using DRF. Hopefully, others new to drf will find this easier.

谢谢@umut和@prashant。我正在使用DRF清楚地分享我的版本。希望其他新的drf会发现这更容易。

def Users_get(self,request,user_token): 
        if request.method == 'GET':
            queryset = Users.objects.filter(user_token=user_token)
            paginator = PageNumberPagination()
            result_page = paginator.paginate_queryset(queryset, request)
            serializer = UsersSerializer(result_page,many=True)
            return paginator.get_paginated_response(serializer.data)

This gave me response with next and previous url links.

这让我回答了下一个和之前的网址链接。

#1


0  

In code below entire viewset is designed GET POST PUT DELETE also your query regarding pagination over filtered query is also handled. Pagination is done using Paginator its a built-in in django

在下面的代码中,整个视图集被设计为GET POST PUT DELETE,您也可以处理有关已过滤查询的分页的查询。分页是使用Paginator完成的,它是django内置的

For docs cover most of the part go to django docs for that. DRF docs can be confusing sometimes but django docs are finely descriptive and easy to implement

对于文档,大部分内容都是为了django docs。 DRF文档有时会令人困惑,但django文档具有良好的描述性且易于实现

views.py

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
@api_view(['GET', 'POST'])
def product_list(request):
    if request.method == 'GET':
        products = Product.objects.all()
        product_make_up = Product.objects.filter(item_category__exact='Make Up')[:3]
        product_skincare = Product.objects.filter(item_category__exact='Skin Care')[:3]
        product_fragrance = Product.objects.filter(item_category__exact='Fragrance')[:3]
        product_personal_care = Product.objects.filter(item_category__exact='Personal Care')[:3]
        product_hair_care = Product.objects.filter(item_category__exact='Hair Care')[:3]
        product_item_category = QuerySetChain(product_make_up,
                                          product_skincare,
                                          product_fragrance,
                                          product_personal_care,
                                          product_hair_care)
        item_cates = request.query_params.get('item_category',None)
        if item_cates is not None:
             product = products.filter(item_category=item_cates)
             paginator = Paginator(product,5)
             page = request.query_params.get('page')
             product = paginator.page(page)
             try:
                 product = paginator.page(page)
             except PageNotAnInteger:
                 product = paginator.page(1)
             except EmptyPage:
                 product = pagintor.page(paginator.num_pages)
                 serializer = ProductSerializer(product, many=True)
    else:
        paginator = Paginator(product_item_category,15)
        page = request.query_params.get('page')
        product_item_category = paginator.page(page)
        try:
            product_item_category = paginator.page(page)
        except PageNotAnInteger:
            product_item_category = paginator.page(1)
        except EmptyPage:
            product_item_category = pagintor.page(paginator.num_pages)
        serializer = ProductSerializer(product_item_category, many=True)    
    return Response(serializer.data)
elif request.method == 'POST':
    serializer = ProductSerializer( data=request.data)
    # data.encode("base64")
    if serializer.is_valid():
        serializer.save()
        res_msg = {'Success_Message' : 'Successful','Success_Code' : 200}
        return Response(res_msg)
    else:
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def product_detail(request, pk):
"""
Get, udpate, or delete a specific task
"""
    try:
        product = Product.objects.get(pk=pk)
    except Product.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = ProductSerializer(product)
        return Response(serializer.data , status=status.HTTP_201_CREATED)

    elif request.method == 'PUT':
        serializer = ProductSerializer(product, data=request.data)
        if serializer.is_valid():
            serializer.save()
        return Response(serializer.data)
        else:
            return Response(
            serilizer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        product.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

#2


0  

That is what I do for pagination, filtering, ordering etc... First you need to pip install django-filter (https://github.com/alex/django-filter)

这就是我为分页,过滤,订购等所做的...首先你需要pip install django-filter(https://github.com/alex/django-filter)

settings.py

REST_FRAMEWORK = {

    . . . 

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'DEFAULT_FILTER_BACKENDS': (
        'rest_framework.filters.DjangoFilterBackend',
    ),
    'PAGE_SIZE': 1000

    . . .

}

views.py

class UserViewSet(viewsets.ModelViewSet):
    lookup_field = 'id'
    queryset = Users.objects.order_by('id')
    serializer_class = AccountSerializer
    filter_backends = (SearchFilter, OrderingFilter)
    search_fields = ('^id', '^first_name', '^last_name', '^email', ^username',)

I am using AngularJS,

我正在使用AngularJS,

function getUserList(limit, pageNumber, search, ordering) {

    var def = $q.defer();
    offset = (pageNumber -1) * limit;
    $http.get(API_URL +
        '?limit=' +limit +
        '&offset=' + offset +
        '&search=' + search +
        '&ordering=' + ordering)

    .success(function(data){
        def.resolve(data);
    })
    .error(function(data){
        def.resolve(data);
    });

    return def.promise;
}

Example query:

http://127.0.0.1:8000/user/?limit=10&offset=0&search=%20&ordering=id

#3


0  

Thanks @umut and @prashant. I am sharing my version plainly using DRF. Hopefully, others new to drf will find this easier.

谢谢@umut和@prashant。我正在使用DRF清楚地分享我的版本。希望其他新的drf会发现这更容易。

def Users_get(self,request,user_token): 
        if request.method == 'GET':
            queryset = Users.objects.filter(user_token=user_token)
            paginator = PageNumberPagination()
            result_page = paginator.paginate_queryset(queryset, request)
            serializer = UsersSerializer(result_page,many=True)
            return paginator.get_paginated_response(serializer.data)

This gave me response with next and previous url links.

这让我回答了下一个和之前的网址链接。