简体   繁体   English

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

[英]Pagination based on filtered results in Django Rest Framework

I have a simple filtering in my get function which needs to be paginated. 我的get函数中有一个简单的过滤,需要分页。 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 以下是我的代码

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的人的。

In code below entire viewset is designed GET POST PUT DELETE also your query regarding pagination over filtered query is also handled. 在整个视图集下面的代码中,设计了GET POST PUT DELETE,还处理了有关通过过滤查询进行的分页的查询。 Pagination is done using Paginator its a built-in in django 分页使用Django内置的Paginator完成

For docs cover most of the part go to django docs for that. 有关文档的大部分内容,请转到Django文档 DRF docs can be confusing sometimes but django docs are finely descriptive and easy to implement DRF文档有时会令人困惑,但Django文档具有很好的描述性,易于实现

views.py 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)

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-filterhttps://github.com/alex/django-filter

settings.py settings.py

REST_FRAMEWORK = {

    . . . 

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

    . . .

}

views.py 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

Thanks @umut and @prashant. 谢谢@umut和@prashant。 I am sharing my version plainly using DRF. 我使用DRF明确共享我的版本。 Hopefully, others new to drf will find this easier. 希望其他对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. 这给了我下一个和上一个URL链接的响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM