is_paginated不适用于django Generic Views

时间:2015-10-30 07:53:11

标签: python django pagination django-crispy-forms

我在我的几个页面中一直使用django内置分页(is_paginated)。他们都很好。除了搜索页面,其中分页应仅基于筛选的查询集显示。

我已经通过其他几个帖子进行了检查,但它没有多大帮助。

How do I use pagination with Django class based generic ListViews?

Django template tag exception

这是我到目前为止的迷你版本: -

1)views.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)

------------------的 更新 -------------- ----

虽然我理解丹尼尔罗斯曼的答案,但由于我对django相当新,我不确定如何实现整个事情,大量的&#34; X无法访问,X不是Y&的属性#34;经过多次挖掘,我在同一事件上找到了一些其他有用的帖子。

Django: Search form in Class Based ListView

Updating context data in FormView form_valid method?

Django CBV: Easy access to url parameters in get_context_data()?

Django class based view ListView with form

URL-parameters and logic in Django class-based views (TemplateView)

我遇到的另一个问题是我无法使用self.kwargs访问URL中的参数,就像大多数帖子中建议的那样。在上面发布的最后一个链接中,Ngenator提到必须使用request.GET.get(&#39;参数&#39;)访问URL参数。我用过它,它对我来说很好。

通过组合所有内容,这里是我修改过的编码。以防任何人遇到与我相同的问题。

1)views.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进行分页。节省了我很多时间!好东西......

2 个答案:

答案 0 :(得分:1)

您已经专门覆盖了get方法,以便它定义自己的上下文,并且从不调用默认方法,因此当然没有任何默认上下文栏可用。

不要这样做;你应该几乎永远不会覆盖get和post方法。您应该将所有表单内容直接移到get_queryset

答案 1 :(得分:1)

正在工作

views.py

class UserListView(ListView):
    model = User
    template_name = 'user_list.html'
    context_object_name = 'users'
    paginate_by = 10

    def get_queryset(self):
        return User.objects.all()

templates / user_list.html

  {% if is_paginated %}
  <nav aria-label="Page navigation conatiner">
    <ul class="pagination justify-content-center">
      {% if page_obj.has_previous %}
      <li><a href="?page={{ page_obj.previous_page_number }}" class="page-link">&laquo; PREV </a></li>
      {% else %}
      <li class="disabled page-item"><a class="page-link">PREV !</a></li>
      {% endif %}

      {% for i in  %}
        {{ i }}
      {% endfor %}

      {% if page_obj.has_next %}
      <li><a href="?page={{ page_obj.next_page_number }}" class="page-link"> NEXT &raquo;</a></li>
      {% else %}
      <li class="disabled page-item"><a class="page-link">NEXT !</a></li>
      {% endif %}
    </ul>
  </nav>
</div>
{% endif %}