is_paginated不适用于Django通用视图

问题描述 投票:4回答:2

我在几个页面中一直使用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)

------------------ UPDATE ------------------

尽管我理解Daniel Roseman的回答,但是由于我对django相当陌生,所以我不确定如何实现整个过程,遇到很多“ X不可访问,X并非Y的属性”等问题。我在同一件事上发现了其他有用的帖子。

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('parameter')访问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进行分页。节省了我很多时间!好东西...

python django pagination django-crispy-forms
2个回答
1
投票

您专门重写了get方法,以便它定义自己的上下文,并且从不调用默认方法,因此自然没有默认上下文栏可用。

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


0
投票

正在工作

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 %}
© www.soinside.com 2019 - 2024. All rights reserved.