我对这项技术非常陌生,我想使用django_filter对包含结果的表进行分页(在我的情况下,我想过滤来自Book Model的结果,这些结果显示在HTML表中)。
我尝试了所有文档和论坛帖子,但不知道我做错了什么,或者我是否正确地做了什么。
这是我的代码:
模型
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()
你能帮帮我吗?谢谢!
答案 0 :(得分:2)
您需要将已过滤的查询集传递给Paginator,该Paginator可以filterObj.qs
进行访问。
如果要访问视图中的过滤对象,例如,如果要对它们进行分页,则可以执行此操作。他们在f.qs
所以创建一个像这样的分页响应:
book_filter = BookFilter(self.request.GET)
paginator = Paginator(book_filter.qs, self.paginate_by)
答案 1 :(得分:0)
你正在使用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