我一直在我的几个页面中使用 django 内置分页(is_pagination)。他们都工作得很好。除了搜索页面外,分页应该仅根据过滤后的查询集显示。
我已经检查了其他一些线程,但没有多大帮助。
如何使用基于 Django 类的通用 ListView 的分页? https://stackoverflow.com/questions/5907575/how-do-i-use-pagination-with-django-class-based-generic-listviews
Django模板标签异常 https://stackoverflow.com/questions/2524682/django-template-tag-exception
这是我迄今为止所拥有的迷你版本:-
1)视图.py
class SearchBookView(ListView):
template_name = 'books/search_book.html'
paginate_by = '2'
context_object_name = 'book'
form_class = SearchBookForm
def get(self, request):
form = self.form_class(request.GET or None)
if form.is_valid():
filtered_books = self.get_queryset(form)
context = {
'form' : form,
'book' : filtered_books,
}
else:
context = {'form': form}
return render(request, self.template_name, context)
def get_queryset(self, form):
filtered_books = Book.objects.all()
if form.cleaned_data['title'] != "":
filtered_books = filtered_books.filter(
title__icontains=form.cleaned_data['title'])
return filtered_books
def get_context_data(self):
context = super(SearchBookView, self).get_context_data()
return context
2)search_book.html(模板)
{% crispy form %}
{% if book %}
<p>Found {{ book|length }} book{{ book|pluralize }}.</p>
{% for book in book %}
<div class="card">
<div style="height:170px; border:solid #111111;" class="col-md-3">
Ima
</div>
<div class="whole-card col-md-9">
<div class="title">"{{ book.title }}"</div>
<div>{{ book.description }}</div>
<a href="{% url 'book:detail' book.id %}" class="btn">Read More</a>
</div>
</div>
{% endfor %}
{% else %}
<p>No book matched your searching criteria.</p>
{% endif %}
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
{% endif %}
</span>
</div>
{% endif %}
forms.py
class SearchBookForm(forms.Form):
title = forms.CharField(max_length=20)
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.add_input(Submit('search', 'Search', css_class='btn'))
self.helper.form_method = 'GET'
self.helper.layout = Layout('title')
super(SearchBookForm, self).__init__(*args, **kwargs)
------------------UPDATE------------------
虽然我理解 Daniel Roseman 的答案,但由于我对 django 相当陌生,我不确定如何实现整个事情,遇到大量“X 不可访问,X 不是 Y 的属性”等问题。经过大量挖掘,我发现关于同一问题的其他一些有用的帖子。
Django:基于类的 ListView 中的搜索表单 https://stackoverflow.com/questions/13416502/django-search-form-in-class-based-listview
更新 FormView form_valid 方法中的上下文数据? https://stackoverflow.com/questions/6907388/updating-context-data-in-formview-form-valid-method
Django CBV:轻松访问 get_context_data() 中的 url 参数? https://stackoverflow.com/questions/19941969/django-cbv-easy-access-to-url-parameters-in-get-context-data
带有表单的基于 Django 类的视图 ListView https://stackoverflow.com/questions/6406553/django-class-based-view-listview-with-form
Django 基于类的视图 (TemplateView) 中的 URL 参数和逻辑 https://stackoverflow.com/questions/15754122/url-parameters-and-logic-in-django-class-based-views-templateview
我遇到的另一个问题是我无法按照大多数帖子中的建议使用 self.kwargs 访问 URL 中的参数。在我上面发布的最后一个链接中,Ngenator 提到必须使用 request.GET.get('parameter') 来访问 URL 参数。我用过它,它对我来说效果很好。
通过结合所有内容,这是我修改后的代码。以防万一有人遇到和我一样的问题。
1) 视图.py
class SearchBookView(ListView):
template_name = 'books/search_book.html'
paginate_by = '3'
context_object_name = 'book_found'
form_class = SearchBookForm
model = Book
def get_queryset(self):
object_list = self.model.objects.all()
title = self.request.GET.get('title', None)
if title is not None and title != "":
object_list = object_list.filter(title__icontains=title)
else:
object_list = []
return object_list
def get_context_data(self):
context = super(SearchBookView, self).get_context_data()
form = self.form_class(self.request.GET or None)
context.update({
'form': form,
})
return context
2)search_book.html(模板)
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load staticfiles %}
{% load bootstrap_pagination %}
{% block title %}Search Page{% endblock %}
{% block content %}
<div class="container">
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
{% crispy form %}
{% if book_found %}
<p>Found {{ paginator.count }} book{{ book_found_no|pluralize }}.</p>
{% for book in book_found %}
<div class="wholecard">
<div style="height:170px; border:solid #111111;" class="col-md-3">
Image
</div>
<div class="card col-md-9">
<div class="card-title">"{{ book.title }}"</div>
<div>{{ book.description }}</div>
<a href="{% url 'books:detail' book.id %}" class="btn">Read More</a>
</div>
</div>
{% endfor %}
{% else %}
<p>No book matched your searching criteria.</p>
{% endif %}
{% bootstrap_paginate page_obj %}
</div>
{% endblock %}
我最终也使用 jmcclell 的 bootstrap-pagination 来进行分页。节省了我很多时间!好东西...