django-filter使用分页

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django-filter使用分页相关的知识,希望对你有一定的参考价值。

我正在使用django-filter程序包在我的列表视图中提供搜索功能。

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

到目前为止,我已经在django-filter上尝试了以下方法:

views.py
答案

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

  1. 为模型创建过滤器类:

    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}) 上:

    my_project/my_app/filters.py
  2. 每个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', ...] 对象都有一个FilterSet属性,其中包含过滤的查询集,甚至可以[.qs

  3. 我们将分页override it if you want.qs属性:

    MyModelFilter上:

    my_project/my_app/views.py

就在那里!


PS_1:根据我的经验,Django过滤器为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_2:如果您要使用DRF,我已经写了一个示例,说明如何在基于函数的视图中使用分页,可以轻松地与"plays" better with Django Rest Framework结合使用:

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)

我写了这个:

<li><a href="?page={{ i }}">{{ i }}</a></li>

我希望这会有所帮助:)

另一答案

这里最重要的部分是[如何在模板中构造URL

您可能有

{% if 'whatever_parameter_you_use_to_filter' in request.get_full_path %}
   <li><a href="{{ request.get_full_path }}&page={{ i }}"{{ i }}</a></li>
{% else %}
   <li><a href="?page={{ i }}">{{ i }}</a></li>
{% endif %}

如果仅使用它在初始分页结果之间进行切换,那将是非常好的。

但是棘手的部分是,当您使用{% if pages.has_previous %} <li><a href="?page={{ pages.previous_page_number }}">Prev</a></li> {% endif %} 过滤器时,查询字符串(在'?'之后的那部分将获得全新的键值对,而忽略了django-fitler或类似的字符。

因此,要使分页与过滤后的结果一起使用,当单击“下一步”或“上一步”按钮时-?page=2的键值中,还需要将django-fitler成对传递。

如@stathoula所述,您需要检查查询字符串中是否已经存在至少一个过滤器字段。如果是,那么您需要使用已经存在的键值对,然后使用新的&page=5对。

[这似乎很简单,但是我不得不做一些小小的改动,以免在用户单击箭头时在查询字符串中一遍又一遍地重复&page=3

就我而言,我使用'title'作为过滤器,因此我需要检查它是否已经存在。

这是我为我的项目所做的完美工作的摘要。

templates / pagination.html

&page=1

这里是视图,以防万一:

app / views.py

<div class="paginator">

    {% with request.get_full_path as querystring %}
        <ul class="pagination nav navbar-nav">

            <!-- Previous page section -->
            {% if pages.has_previous %}
                {% if 'title' in querystring %}
                    {% if 'page' in querystring %}
                        <li class="paginator {% if pages.number == page %}active{% endif %}">
                            <a href="{{ querystring|slice:":-7" }}&page={{ pages.previous_page_number }}">Prev</a>
                        </li>
                    {% else %}
                        <li class="paginator {% if pages.number == page %}active{% endif %}">
                            <a href="{{ querystring }}&page={{ pages.previous_page_number }}">Prev</a>
                        </li>
                    {% endif %}
                {% else %}
                    <li class="paginator {% if pages.number == page %}active{% endif %}">
                        <a href="?page={{ pages.previous_page_number }}">Prev</a>
                    </li>
                {% endif %}
            {% endif %}

            <!-- All pages section -->
            {% for page in pages.paginator.page_range %}
                {% if 'title' in querystring %}
                    {% if 'page' in querystring %}
                        <li class="paginator {% if pages.number == page %}active{% endif %}">
                            <a href="{{ querystring|slice:":-7" }}&page={{ page }}">{{ page }}</a>
                        </li>
                    {% else %}
                        <li class="paginator {% if pages.number == page %}active{% endif %}">
                            <a href="{{ querystring }}&page={{ page }}">{{ page }}</a>
                        </li>
                    {% endif %}
                {% else %}
                    <li class="paginator {% if pages.number == page %}active{% endif %}">
                        <a href="?page={{ page }}">{{ page }}</a>
                    </li>
                {% endif %}
            {% endfor %}

            <!-- Next page section -->
            {% if pages.has_next %}
                {% if 'title' in querystring %}
                    {% if 'page' in querystring %}
                        <li class="paginator {% if pages.number == page %}active{% endif %}">
                            <a href="{{ querystring|slice:":-7" }}&page={{ pages.next_page_number }}">Next</a>
                        </li>
                    {% else %}
                        <li class="paginator {% if pages.number == page %}active{% endif %}">
                            <a href="{{ querystring }}&page={{ pages.next_page_number }}">Next</a>
                        </li>
                    {% endif %}
                {% else %}
                    <li class="paginator {% if pages.number == page %}active{% endif %}">
                        <a href="?page={{ pages.next_page_number }}">Next</a>
                    </li>
                {% endif %}
            {% endif %}

        </ul>
    {% endwith %}

</div>

这是一个工作示例:

“”

另一答案

[我花了一些时间找到DRYer和更清洁的解决方案来解决此问题,我认为最好的解决方案是使用模板标签的解决方案。

def index(request):
    condo_list = Condo.objects.all().order_by('-timestamp_created')
    condo_filter = CondoFilter(request.GET, queryset=condo_list)

    paginator = Paginator(condo_filt

以上是关于django-filter使用分页的主要内容,如果未能解决你的问题,请参考以下文章

modx - 当我在同上片段中使用“&documents =”参数时,分页不起作用

在大表上使用 Django-Filter 以及 DataTables2

需要用ajax调用实现django-filter

如何在 ListAPIView 中使用 django-filter 对过滤结果进行排序

将 django-select2 与 django-filters 连接

Python后台开发偷懒神器Django-Filter介绍与刁钻需求的实现方法