如何使用基于Django类的通用ListView进行分页?

gat*_*ath 176 django

如何使用Django 1.3分页?

文档对此不是很清楚.

  • 怎么回事views.py

  • 什么到我的模板?

  • 什么到我的URLconf文件?

小智 330

我想你要求提供有关使用基于新类的视图分页的信息,因为使用传统的基于函数的视图,它很容易找到.我发现只需设置paginate_by变量就足以激活分页.请参阅基于类的通用视图.

例如,在你的views.py:

import models
from django.views.generic import ListView

class CarListView(ListView):
    model = models.Car      # shorthand for setting queryset = models.Car.objects.all()
    template_name = 'app/car_list.html'  # optional (the default is app_name/modelNameInLowerCase_list.html; which will look into your templates folder for that path and file)
    context_object_name = "car_list"    #default is object_list as well as model's_verbose_name_list and/or model's_verbose_name_plural_list, if defined in the model's inner Meta class
    paginate_by = 10  #and that's it !!
Run Code Online (Sandbox Code Playgroud)

在你的模板(car_list.html),您可以包括这样的分页部分(我们有一些情境变量可用:is_paginated,page_obj,和paginator).

{# .... **Normal content list, maybe a table** .... #}
{% if car_list %}
    <table id="cars">
        {% for car in car_list %}
            <tr>
                <td>{{ car.model }}</td>
                <td>{{ car.year }}</td>
                <td><a href="/car/{{ car.id }}/" class="see_detail">detail</a></td>
            </tr>
        {% endfor %}
    </table>
    {# .... **Now the pagination section** .... #}
    {% if is_paginated %}
        <div class="pagination">
            <span class="page-links">
                {% if page_obj.has_previous %}
                    <a href="/cars?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="/cars?page={{ page_obj.next_page_number }}">next</a>
                {% endif %}
            </span>
        </div>
    {% endif %}
{% else %}
    <h3>My Cars</h3>
    <p>No cars found!!! :(</p>
{% endif %}
{# .... **More content, footer, etc.** .... #}
Run Code Online (Sandbox Code Playgroud)

要显示的页面由GET参数指示,只需添加?page=n到URL即可.

  • 我不喜欢您可以替换它的硬编码网址:<a href="?page={{page_obj.previous_page_number }}">之前的</a> (30认同)
  • 仅供参考,您也可以直接在urls.py:url(r'^cars/$',ListView.as_view(model = Car,paginate_by = 10)), (27认同)
  • 我一直这样做,但我发现的问题是,当我对查询集中的对象进行额外处理时,它会将它们应用于数据库中的所有结果.因此,对于返回100个对象但每页仅显示10个对象的查询,将对100个对象执行额外处理. (2认同)

Yan*_*Sky 40

假设,我在app/models.py中有一个名为FileExam(models.Model):

应用程序/ models.py

class FileExam(models.Model):
    myfile = models.FileField(upload_to='documents/%Y/%m/%d')
    date = models.DateTimeField(auto_now_add=True, blank=True)
    teacher_name = models.CharField(max_length=30)
    status = models.BooleanField(blank=True, default=False)
Run Code Online (Sandbox Code Playgroud)

应用程序/ views.py

from app.models import FileExam
from django.core.paginator import Paginator
from django.core.paginator import EmptyPage
from django.core.paginator import PageNotAnInteger

class FileExamListView(ListView):
    model = FileExam
    template_name = "app/exam_list.html"
    paginate_by = 10


    def get_context_data(self, **kwargs):
        context = super(SoalListView, self).get_context_data(**kwargs) 
        list_exam = FileExam.objects.all()
        paginator = Paginator(list_exam, self.paginate_by)

        page = self.request.GET.get('page')

        try:
            file_exams = paginator.page(page)
        except PageNotAnInteger:
            file_exams = paginator.page(1)
        except EmptyPage:
            file_exams = paginator.page(paginator.num_pages)

        context['list_exams'] = file_exams
        return context
Run Code Online (Sandbox Code Playgroud)

只有在AA变化不大get_context_data,并添加分页代码Django文档在这里

应用程序/模板/应用/ exam_list.html

正常内容列表

<table id="exam">
  {% for exam in list_exams %}
  <tr>
    <td>{{ exam.myfile }}</td>
    <td>{{ exam.date }}</td>
    <td>.....</td>
  </tr>
  {% endfor %}
</table>
Run Code Online (Sandbox Code Playgroud)

分页部分

{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
    <li>
        <span><a href="?page={{ page_obj.previous_page_number }}">Previous</a></span>
    </li>
{% endif %}
    <li class="">
        <span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.</span>
    </li>
{% if page_obj.has_next %}
    <li>
        <span><a href="?page={{ page_obj.next_page_number }}">Next</a></span>
    </li>
{% endif %}
</ul>
{% else %}
    <h3>Your File Exam</h3>
    <p>File not yet available</p>
{% endif %}
Run Code Online (Sandbox Code Playgroud)

应用程序/ urls.py

urlpatterns = [
url(
    r'^$', views.FileExamListView.as_view(), name='file-exam-view'),
), 
... ]
Run Code Online (Sandbox Code Playgroud)

  • 是的,对!此答案已由Yacin 先生编辑。谢谢你,亚辛先生。 (2认同)