一尘不染

Django过滤器使用分页

django

我正在使用该django-filter软件包在列表视图中提供搜索功能。

现在,我还要向该视图添加分页。
我正在尝试将分页与过滤后的查询集结合起来,但是我不知道如何继续。

到目前为止,我已经尝试了以下方法views.py

def search(request):
    qs = local_url.objects.filter(global_url__id=1).all()
    paginator = Paginator(qs, 25)
    page = request.GET.get('page')
    try:
        pub = paginator.page(page)
    except PageNotAnInteger:
        pub = paginator.page(1)
    except EmptyPage:
       pub = paginator.page(paginator.num_pages)
    url_filter = PublicationFilter(request.GET, queryset=qs)
    return render(request, 'ingester/search_list.html', {'filter': url_filter, 'publication':pub})

阅读 731

收藏
2020-03-30

共1个答案

一尘不染

要使用Django过滤器并对过滤后的结果进行分页,你可以执行以下操作:

  1. 为你的模型创建一个过滤器类:

my_project/my_app/filters.py:

import django_filters

class MyModelFilter(django_filters.FilterSet):
    class Meta:
        model = MyModel
        # Declare all your model fields by which you will filter
        # your queryset here:
        fields = ['field_1', 'field_2', ...]
  1. 每个FilterSet对象都有一个.qs包含过滤查询集的属性,如果需要,你甚至可以覆盖它。

  2. 我们将对我们的.qs财产进行分页MyModelFilter

my_project/my_app/views.py

from . import filters
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def my_view(request):
    # BTW you do not need .all() after a .filter() 
    # local_url.objects.filter(global_url__id=1) will do
    filtered_qs = filters.MyModelFilter(
                      request.GET, 
                      queryset=MyModel.objects.all()
                  ).qs
    paginator = Paginator(filtered_qs, YOUR_PAGE_SIZE)

    page = request.GET.get('page')
    try:
        response = paginator.page(page)
    except PageNotAnInteger:
        response = paginator.page(1)
    except EmptyPage:
        response = paginator.page(paginator.num_pages)

    return render(
        request, 
        'your_template.html', 
        {'response': response}
    )

在那里,你拥有了!

PS_1:根据我的经验,使用Django过滤器时,使用Django Rest Framework可以更好地“玩”。
PS_2:如果你要使用DRF,我已经写了一个示例,说明如何在基于函数的视图中使用分页,可以轻松地将其与结合使用FilterSet

@api_view(['GET',])
def my_function_based_list_view(request):
    paginator = PageNumberPagination()
    filtered_set = filters.MyModelFilter(
                       request.GET, 
                       queryset=MyModel.objects.all()
                   ).qs
    context = paginator.paginate_queryset(filtered_set, request)
    serializer = MyModelSerializer(context, many=True)
    return paginator.get_paginated_response(serializer.data)
2020-03-30