【问题标题】:is_paginated not working for django Generic Viewsis_paginated 不适用于 django 通用视图
【发布时间】:2016-01-30 14:09:37
【问题描述】:

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

------------------更新------------- ----

虽然我理解 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 的引导分页进行分页。节省了我很多时间!好东西……

【问题讨论】:

    标签: python django pagination django-crispy-forms


    【解决方案1】:

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

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

    【讨论】:

    • 这也是我所怀疑的。我尝试调用 get_context_data() 并执行 context.update 而不是在 get() 方法中定义我自己的上下文。但我收到错误。这是执行搜索功能的正确方法还是有其他更好的方法?
    • 好吧,就像我说的,你应该完全删除get(),并在get_queryset() 中执行表单逻辑。
    【解决方案2】:

    它正在工作

    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()
    

    模板/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 %}
    

    【讨论】:

      猜你喜欢
      • 2017-11-10
      • 2018-06-28
      • 1970-01-01
      • 2015-02-03
      • 2015-07-18
      • 2020-05-08
      • 2015-04-27
      • 2014-08-02
      相关资源
      最近更新 更多