is_paginated 不适用于 django 通用视图 [英] is_paginated not working for django Generic Views

查看:67
本文介绍了is_paginated 不适用于 django 通用视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在我的几个页面中使用 django 内置分页 (is_paginated).他们都工作正常.搜索页面除外,其中分页应仅基于过滤后的查询集出现.

我已经检查了其他几个线程,但没有太大帮助.

如何在 Django 中使用分页基于类的通用 ListViews?

Django 模板标签异常

这是我目前所拥有的迷你版:-

1)views.py

class SearchBookView(ListView):模板名称 = '书籍/search_book.html'paginate_by = '2'context_object_name = '书'form_class = SearchBookFormdef get(self, request):form = self.form_class(request.GET or None)如果 form.is_valid():Filtered_books = self.get_queryset(form)上下文 = {'形式':形式,书":filtered_books,}别的:上下文 = {'形式':形式}返回渲染(请求,self.template_name,上下文)def get_queryset(self, form):Filtered_books = Book.objects.all()如果 form.cleaned_data['title'] != "":过滤书=过滤书.过滤器(title__icontains=form.cleaned_data['title'])返回filtered_booksdef get_context_data(self):context = super(SearchBookView, self).get_context_data()返回上下文

2) search_book.html(模板)

{% 脆皮形式 %}{% 如果预订 %}<p>找到 {{ book|length }} book{{ book|pluralize }}.</p>{% for book in book %}<div class="card"><div style="height:170px; border:solid #111111;"class="col-md-3">我是一个

<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">阅读更多</a>

{% 结束为 %}{% 别的 %}<p>没有书符合您的搜索条件.</p>{% 万一 %}{% if is_paginated %}<div class="分页"><span class="page-links">{% if page_obj.has_previous %}<a href="?page={{ page_obj.previous_page_number }}">previous</a>{% 万一 %}<span class="page-current">第 {{ page_obj.number }} 页,共 {{ page_obj.paginator.num_pages }}.</span>{% if page_obj.has_next %}<a href="?page={{ page_obj.next_page_number }}">next</a>{% 万一 %}</span>

{% 万一 %}

forms.py

class SearchBookForm(forms.Form):标题 = 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:在基于类的 ListView 中搜索表单

在 FormView form_valid 方法中更新上下文数据?

Django CBV:轻松访问 urlget_context_data() 中的参数?

基于 Django 类的带有表单的视图 ListView

Django 类中的 URL-参数和逻辑-基于视图(TemplateView)

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

通过组合所有内容,这是我修改后的代码片段.以防万一有人和我有同样的问题.

1) views.py

class SearchBookView(ListView):模板名称 = '书籍/search_book.html'paginate_by = '3'context_object_name = 'book_found'form_class = SearchBookForm模型 = 书def get_queryset(self):object_list = self.model.objects.all()title = self.request.GET.get('title', None)如果 title 不是 None 且 title != "":object_list = object_list.filter(title__icontains=title)别的:object_list = []返回对象列表def get_context_data(self):context = super(SearchBookView, self).get_context_data()form = self.form_class(self.request.GET 或 None)上下文.更新({'形式':形式,})返回上下文

2) search_book.html(模板)

{% 扩展 "base.html" %}{% 加载crispy_forms_tags %}{% 加载静态文件 %}{% 加载 bootstrap_pagination %}{% 区块标题 %}搜索页面{% endblock %}{% 块内容 %}<div class="容器">{% if form.errors %}<p style="颜色:红色;">请更正下面的错误{{ form.errors|pluralize }}.</p>{% 万一 %}{% 酥脆形式 %}{% if book_found %}<p>找到 {{ paginator.count }} 本书{{ book_found_no|pluralize }}.</p>{% for book_found %}<div class="全卡"><div style="height:170px; border:solid #111111;"class="col-md-3">图像

<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">阅读更多</a>

{% 结束为 %}{% 别的 %}<p>没有书符合您的搜索条件.</p>{% 万一 %}{% bootstrap_paginate page_obj %}

{% 结束块 %}

我最终也使用 jmcclell 的 bootstrap-pagination 进行分页.为我节省了很多时间!好东西...

解决方案

正常运行

views.py

class UserListView(ListView):模型 = 用户模板名称 = 'user_list.html'context_object_name = '用户'paginate_by = 10def get_queryset(self):返回 User.objects.all()

模板/user_list.html

 {% if is_paginated %}<nav aria-label="页面导航容器"><ul class="pagination justify-content-center">{% if page_obj.has_previous %}<li><a href="?page={{ page_obj.previous_page_number }}" class="page-link">&laquo;上一篇</a></li>{% 别的 %}<li class="disabled page-item"><a class="page-link">PREV !</a></li>{% 万一 %}{% for i in %}{{ 一世 }}{% 结束为 %}{% if page_obj.has_next %}<li><a href="?page={{ page_obj.next_page_number }}" class="page-link">下一个&raquo;</a></li>{% 别的 %}<li class="disabled page-item"><a class="page-link">NEXT !</a></li>{% 万一 %}</nav>

{% 万一 %}

I've been using django built-in pagination (is_paginated) in few of my pages. They are all working fine. Except for the search page where the pagination should only appear based on the filtered queryset.

I've checked through few other thread but it ain't helping much.

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

Django template tag exception

Here's a mini version of what I have so far:-

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

{% 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------------------

Though I understand Daniel Roseman's answer but as I am fairly new to django, I am not sure how to implement the whole thing, hitting plenty of "X not accessible, X is not attribute of Y" and etc. After much digging, I found some other useful posts on this same matter.

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)

Another problem I encounter is I am unable to access the parameters in URL using self.kwargs as what suggested in most of the posts. In the final link I posted above, Ngenator mentioned that URL parameters has to be accessed using request.GET.get('parameter'). I used that and it's working fine for me.

By combining everything, here's the revised piece of coding I have. Just in case anyone is having the same problem as me.

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

{% 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 %}

And I ended up using jmcclell's bootstrap-pagination also for pagination. Saved me lots of time! Good stuff...

解决方案

It's working

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 %}

这篇关于is_paginated 不适用于 django 通用视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
Python最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆