【问题标题】:Paginate results from django_filter对 django_filter 的结果进行分页
【发布时间】:2018-04-03 23:41:19
【问题描述】:

我对这项技术非常陌生,我想使用 django_filter 对包含结果的表进行分页(在我的情况下,我想过滤显示在 HTML 表中的 Book Model 的结果)。

我尝试了所有文档和论坛帖子,但不知道我做错了什么或者我做的是否正确。

这是我的代码:

模型

class Book(models.Model):

    name = models.CharField(max_length=350)
    author = models.CharField(max_length=350)
    category = models.CharField(max_length=200)

    def __str__(self):
        return self.name

过滤器

class BookFilter(django_filters.FilterSet):
    name = django_filters.CharFilter(lookup_expr='icontains')
    author = django_filters.CharFilter(lookup_expr='icontains')
    category = django_filters.CharFilter(lookup_expr='icontains')

    class Meta:
        model = Book
        ields = ['name', 'author', 'category',]

观看次数

class SearchBooksView(ListView):
    template_name = "booksearch.html"
    book_list = Book.objects.all()
    context_object_name = 'book_list'
    paginate_by = 3

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        book_filter = BookFilter(self.request.GET)
        paginator = Paginator(book_filter, self.paginate_by)
        page = self.request.GET.get('page')
            try:
                book_list = paginator.page(page)
            except PageNotAnInteger:
                book_list = paginator.page(1)
            except EmptyPage:
                book_list = paginator.page(paginator.num_pages)

        context['book_list'] = book_list

        return context

** html **

<h1 class="h1"> Search Books </h1>
<form method="get">
    {{ book_filter.form.as_p }}
    <button type="submit">Search</button>
</form>
<div class="container">
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Author</th>
                <th>Category</th>
            </tr>
        </thead>
        <tbody>
        {% for book in book_list %}
            <tr>
                <td>{{ book.name }}</td>
                <td>{{ book.author }}</td>
                <td>{{ book.category }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    {% if is_paginated %}
        <ul class="pagination">
        {% if page_obj.has_previous %}
            <li>
                <span><a href="?page={{ page_obj.previous_page_number }}">Previous</a></span>
            </li>
        {% endif %}
            <li class="">
                <span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.</span>
            </li>
        {% if page_obj.has_next %}
            <li>
                <span><a href="?page={{ page_obj.next_page_number }}">Next</a></span>
            </li>
        {% endif %}
        </ul>
        {% else %}
            <p>No books available</p>
        {% endif %}
</div>

我得到这个代码:

paginator.py, line 84, in count return len(self.object_list)

'BookFilter' has no len()

你能帮帮我吗?谢谢!

【问题讨论】:

    标签: python django filter pagination


    【解决方案1】:

    您需要将过滤后的查询集传递给分页器,该分页器可以通过filterObj.qs 访问。

    来自django_filter docs

    如果您想访问视图中过滤的对象,例如,如果您想对它们进行分页,您可以这样做。他们在 f.qs 中

    所以创建一个这样的分页响应:

    book_filter = BookFilter(self.request.GET)
    paginator = Paginator(book_filter.qs, self.paginate_by)
    

    【讨论】:

      【解决方案2】:

      您正在使用来自 django 的通用 ListView 对吗?该视图已经为您处理了分页,您应该重构代码:

      class SearchBooksView(ListView):
          model = Book
          template_name = "booksearch.html"
          context_object_name = 'book_list'
          paginate_by = 3
      
          def get_queryset(self):
              return BookFilter(self.request.GET, queryset=Book.objects.all()).qs
      

      【讨论】:

        猜你喜欢
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-20
        • 2013-05-13
        • 2019-06-24
        • 1970-01-01
        相关资源
        最近更新 更多