Django过滤与分页

时间:2018-01-31 16:25:06

标签: django django-filter django-pagination

我正在尝试按照以下教程对django过滤器进行分页,但是教程似乎缺少了一些内容,并且我无法使用基于函数的视图方法显示分页。

https://simpleisbetterthancomplex.com/tutorial/2016/08/03/how-to-paginate-with-django.html

My updated users_list.html is the following:

   {% extends 'base.html' %}

{% load widget_tweaks %}

{% block content %}
  <form method="get">
    <div class="well">
      <h4 style="margin-top: 0">Filter</h4>
      <div class="row">
        <div class="form-group col-sm-4 col-md-4">
          <label/> 3-4 User ID
          {% render_field filter.form.employeentname class="form-control" %}
        </div>
        <div class="form-group col-sm-4 col-md-4">
          <label/> First Name
          {% render_field filter.form.employeefirstname class="form-control" %}
        </div>
        <div class="form-group col-sm-4 col-md-4">
          <label/> Last Name
          {% render_field filter.form.employeelastname class="form-control" %}
        </div>

        <div class="form-group col-sm-4 col-md-4">
          <label/> Status
          {% render_field filter.form.statusid class="form-control" %}
        </div>

        <div class="form-group col-sm-4 col-md-4">
          <label/> Title
          {% render_field filter.form.positiondesc class="form-control" %}
        </div>
      </div>
      <button type="submit" class="btn btn-primary">
        <span class="glyphicon glyphicon-search"></span> Search
      </button>
    </div>
  </form>
  <form action = "{% url 'results' %}" form method = "POST">
        {% csrf_token %}
  <table class="table table-bordered">
    {{ form.as_table }}
    <thead>
      <tr>
        <th>3-4</th>
        <th>First name</th>
        <th>Last name</th>
        <th>Title</th>
        <th>Status</th>
        <th></th>

      </tr>
    </thead>
    <tbody>
      {% for user in filter.qs %}
        <tr>
          <td>{{ user.employeentname }}</td>
          <td>{{ user.employeefirstname }}</td>
          <td>{{ user.employeelastname }}</td>
          <td>{{ user.positiondesc }}</td>
          <td>{{ user.statusid }}</td>
          <td><input type="checkbox" name="usercheck" value = "{{user.employeentname}}" />&nbsp;</td>

        </tr>
      {% empty %}
        <tr>
          <td colspan="5">No data</td>
        </tr>
      {% endfor %}
    </tbody>
  </table>



          <button class="btn btn-primary" type="submit">Select User</button>
        </form>
{% endblock %}

我的观点基于教程,但我使用的是自己的模型:

def user_list(request):
    user_list = Employee.objects.all()
    user_filter = UserFilter(request.GET, queryset=user_list)
    user_list = user_filter.qs
    page = request.GET.get('page', 1)



    paginator = Paginator(user_list.qs, 10)
    try:
        users = paginator.page(page)
    except PageNotAnInteger:
        users = paginator.page(1)
    except EmptyPage:
        users = paginator.page(paginator.num_pages)


    args = {'filter':user_filter, 'users':users}


    return render(request, 'user_list.html', args)

我的目录结构设置如下,也许是它的内容:

enter image description here

from django import forms
from .models import Employee

import django_filters


class UserFilter(django_filters.FilterSet):


    class Meta:
        model = Employee
        fields =  ['employeentname', 'employeefirstname', 'employeelastname', 'statusid', 'positiondesc']





    def __init__(self, *args, **kwargs):
        super(UserFilter, self).__init__(*args, **kwargs)
        # at sturtup user doen't push Submit button, and QueryDict (in data) is empty
        if self.data == {}:
            self.queryset = self.queryset.none()

在移动分页后添加了我的base.html:

{% load static %}<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style type="text/css">
      .page-header {
        margin-top: 0;
      }
    </style>
  </head>
  <body>
    {% include 'includes/header.html' %}
    <div class="container">
      {% block content %}
      {% if users.has_other_pages %}
        <ul class="pagination">
         {% if users.has_previous %}
           <li><a href="?page={{ users.previous_page_number }}">&laquo;</a></li>
         {% else %}
          <li class="disabled"><span>&laquo;</span></li>
       {% endif %}
         {% for i in users.paginator.page_range %}
           {% if users.number == i %}
             <li class="active"><span>{{ i }} <span class="sr-only">(current)
          </span></span></li>
           {% else %}
             <li><a href="?page={{ i }}">{{ i }}</a></li>
           {% endif %}
         {% endfor %}
         {% if users.has_next %}
           <li><a href="?page={{ users.next_page_number }}">&raquo;</a></li>
         {% else %}
           <li class="disabled"><span>&raquo;</span></li>
         {% endif %}
       </ul>
         {% endif %}
      {% endblock %}
    </div>
    <script src="{% static 'js/jquery-3.1.1.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>





    {% block javascript %}

    {% endblock %}
  </body>
</html>

我期待的是我的过滤器为每10个用户分页搜索结果。我现在得到的是整个用户群。过滤器工作正常,这不是分页。

6 个答案:

答案 0 :(得分:3)

您可以像这样分页:

注意:user_filter.qs已过滤结果且user_filter.queryset已取消过滤结果

views.py

var moment = require('moment-timezone');
exports.addcalllog = function(req, res) {
 console.log(timezone);
}

然后在模板中:

      def search(request):
         user_list = Employee.objects.all()
         user_filter = UserFilter(request.GET, queryset=user_list)
         user_list = user_filter.qs


         paginator = Paginator(user_list, 10)
         page = request.GET.get('page', 1)
         try:
            users = paginator.page(page)
         except PageNotAnInteger:
            users = paginator.page(1)
         except EmptyPage:
            users = paginator.page(paginator.num_pages)
         args = {'paginator': paginator,'filter':user_filter, 
           'users':users,}
         return render(request, 'search/user_list.html', args)

   {% for user in users %}
     <tr>
      <td>{{ user.employeeusername }}</td>
      <td>{{ user.employeefirstname }}</td>
      <td>{{ user.employeelastname }}</td>
      <td>{{ user.statusid }}</td>
      <td><input type="checkbox" name="usercheck" />&nbsp;</td>

    </tr>
  {% empty %}
    <tr>
      <td colspan="5">No data</td>
    </tr>
  {% endfor %}
</tbody>

答案 1 :(得分:1)

我现在已经测试过!它对我来说很好。只需用view like the previous answer

分享模板的一部分
      <div class="row">
        <div class="form-group col-sm-4 col-md-3">

          {{ filter.form.row_date.label_tag }}
          {% render_field filter.form.row_date class="form-control" %}

        </div>

        <div class="form-group col-sm-4 col-md-3">
          {{ filter.form.director.label_tag }}
          {% render_field filter.form.director class="form-control" %}
        </div>
        <div class="form-group col-sm-8 col-md-6">
          {{ filter.form.manager.label_tag }}
          {% render_field filter.form.manager class="form-control" %}
        </div> 
        <div class="form-group col-sm-8 col-md-6">
          {{ filter.form.analyst.label_tag }}
          {% render_field filter.form.analyst class="form-control" %}
        </div> 
        <div class="form-group col-sm-8 col-md-6">
        <button type="submit" class="btn btn-primary">
        <span class="glyphicon glyphicon-search"></span> Search
        </button>
        </div>
        </div>
      </div>

    </div>
  </form>

  <table class="table table-bordered" >
    <thead>
      <tr>

        <th>row_date</th>
        <th>Director</th>
        <th>Manager</th>
        <th>Analyst</th>

      </tr>
    </thead>
    <tbody>
      {% for a in users %}
        <tr>
          <td>{{ a.row_date }}</td>
          <td>{{ a.director }}</td>
          <td>{{ a.manager }}</td>
          <td>{{ a.analyst }}</td>

          <td colspan="5">No data</td>
        </tr>
        {% empty %}
        <tr>
          <td colspan="5">No data</td>
        </tr>
        {% endfor %}
      </tbody>
      </table>
    </div>
       {% block javascript %}
    <script src="{% static 'search/js/jquery-3.1.1.min.js' %}"></script>
    <script src="{% static 'search/js/bootstrap.min.js' %}"></script>

     {% endblock %}
  </body>
</html>

答案 2 :(得分:0)

我写了一篇关于在我的博客上使用基于函数的视图实现Django分页的帖子,你可以查看here

我已经讨论了几种在Django中实现分页的方法

答案 3 :(得分:0)

它对我来说很好。 如果仍然如此,它不适合你,节省时间和尝试其他替代方案会更好。

以下是一些建议:

1.请尝试Q objects

2.您可以使用kwargs

做很多事情

3.Django REST Framework Filtering

4.对于类似搜索引擎的能力haystack is a beast - 对于新手来说可能有点复杂。

5.您也可以使用Elastic Search

Views.py

def avail_list(request):
        avails1 = AvailstaticCopy.objects.all().order_by('-row_date')
        avail_filter = AvailFilter(request.GET, queryset=avails1)
        avails1 = avail_filter.qs


        paginator = Paginator(avails1, 144)
        page = request.GET.get('page',1)

        try:
            users = paginator.page(page)
        except PageNotAnInteger:
            users = paginator.page(1)
        except EmptyPage:
            users = paginator.page(paginator.num_pages)


        context = {
            'paginator': paginator,
            'users': users,
            'filter': avail_filter,
        }
        return render(request,'avails/avail_list.html',context)

模板的一部分供参考,其情况类似于问题:

     <div class="row">
        <div class="form-group col-sm-4 col-md-3">

          {{ filter.form.row_date.label_tag }}
          {% render_field filter.form.row_date class="form-control" %}

        </div>

        <div class="form-group col-sm-4 col-md-3">
          {{ filter.form.director.label_tag }}
          {% render_field filter.form.director class="form-control" %}
        </div>
        <div class="form-group col-sm-8 col-md-6">
          {{ filter.form.manager.label_tag }}
          {% render_field filter.form.manager class="form-control" %}
        </div> 
        <div class="form-group col-sm-8 col-md-6">
          {{ filter.form.analyst.label_tag }}
          {% render_field filter.form.analyst class="form-control" %}
        </div> 
        <div class="form-group col-sm-8 col-md-6">
        <button type="submit" class="btn btn-primary">
        <span class="glyphicon glyphicon-search"></span> Search
        </button>
        </div>
        </div>
      </div>

    </div>


  <table class="table table-bordered" >
    <thead>
      <tr>

        <th>row_date</th>
        <th>Director</th>
        <th>Manager</th>
        <th>Analyst</th>

      </tr>
    </thead>
    <tbody>
      {% for a in users %}
        <tr>
          <td>{{ a.row_date }}</td>
          <td>{{ a.director }}</td>
          <td>{{ a.manager }}</td>
          <td>{{ a.analyst }}</td>
        </tr>
        {% empty %}
        <tr>
          <td colspan="5">No data</td>
        </tr>
        {% endfor %}
      </tbody>
      </table>
    </div>
       {% block javascript %}
    <script src="{% static 'search/js/jquery-3.1.1.min.js' %}"></script>
    <script src="{% static 'search/js/bootstrap.min.js' %}"></script>

     {% endblock %}
  </body>
</html>

答案 4 :(得分:0)

我不知道这是否相关,但是在我看来,问题可能出在您设置分页器的位置。您认为

paginator = Paginator(user_list.qs, 10)

但是如果您仔细查看提供的解决方案,则建议您使用

paginator = Paginator(user_list, 10) 

没有.qs,因为您已经在上一行中用user_list = user_filter.qs定义了user_list

答案 5 :(得分:0)


实施步骤

  1. 通过pip install filter-and-pagination安装软件包
  2. 通过from filter_and_pagination import FilterPagination在view.py中导入FilterPagination
  3. 在您的函数中编写下面的代码作为标准...
queryset = FilterPagination.filter_and_pagination(request, Customer)
serialize_data = CustomerSerializer(queryset['queryset'], many=True).data
resultset = {'dataset': serialize_data, 'pagination': queryset['pagination']}
  • 在这段代码Customer中是Django模型&
  • CustomerSerializer是DRF序列化程序类
  1. 在结果集中,它包含数据集和分页数据,采用这种格式(API响应)链接:https://github.com/ashish1997it/filter-pagination-dj#demo
  2. 对于API请求,请遵循PostMan集合链接:https://github.com/ashish1997it/filter-pagination-dj#postman,在标头部分,它将带有一个参数,并要求您根据需要自定义

如果您仍然遇到任何困难,请与我联系:)