如何对基于Django类的泛型ListView使用分页?

如何对基于Django类的泛型ListView使用分页?,django,Django,如何在Django 1.3中使用分页 文件对此不是很清楚 我的视图.py中有什么内容 我的模板中有什么 我的URLconf文件中有什么内容 我想您会询问有关在新的基于类的视图中使用分页的信息,因为在传统的基于函数的视图中,很容易找到分页。我发现只要设置paginate_by变量就足以激活分页。再见 例如,在视图.py中: import models from django.views.generic import ListView class CarListView(ListView):

如何在Django 1.3中使用分页

文件对此不是很清楚

  • 我的
    视图.py中有什么内容

  • 我的模板中有什么

  • 我的URLconf文件中有什么内容


我想您会询问有关在新的基于类的视图中使用分页的信息,因为在传统的基于函数的视图中,很容易找到分页。我发现只要设置
paginate_by
变量就足以激活分页。再见

例如,在
视图.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 !!
在您的模板(
car_list.html
)中,您可以包括这样的分页部分(我们有一些上下文变量可用:
已分页
页面对象
,以及
分页器

{#....**普通内容列表,可能是一个表**..}
{%if car_list%}
{car in car_list%}
{{car.model}}
{{car.year}
{%endfor%}
{#....**现在是分页部分**..}
{%if已分页%}
{%如果页面_obj.has_previous%}
{%endif%}
第{{Page_obj.paginator.num_pages}页中的第{{Page_obj.number}页。
{%如果页面_obj.has_next%}
{%endif%}
{%endif%}
{%else%}
我的车
找不到车!!!:(

{%endif%} {#....**更多内容、页脚等。**...}

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

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

app/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)
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(FileExamListView, 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
urlpatterns = [
url(
    r'^$', views.FileExamListView.as_view(), name='file-exam-view'),
), 
... ]
app/views.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)
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(FileExamListView, 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
urlpatterns = [
url(
    r'^$', views.FileExamListView.as_view(), name='file-exam-view'),
), 
... ]
get_context_data
中只做了一点更改,并从django文档中添加了分页代码

app/templates/app/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>

我们有两种方法可以做到这一点

第一个方法很简单,只需设置类字段
paginate\u by
。我们不需要使用
get\u context\u data
方法

第二种方法有点复杂,但我们可以获得更多关于分页的理解,并定制复杂分页或多个分页。让我们来看看

可以分三步完成

1.覆盖您的
视图的
获取上下文数据的方法。
传递
page_键
页面
,以便我们可以迭代列表并避免硬编码

def get_context_data(self, *, object_list=None, **kwargs):
    context = super().get_context_data()
    df = pd.DataFrame(list(self.model.objects.all().values()))
    ipc = df.groupby('ip')['ip'].count().sort_values(ascending=False)
    urlc = df.groupby('url')['url'].count().sort_values(ascending=False).to_dict()

    ipc = tuple(ipc.to_dict().items())
    urlc = tuple(urlc.items())

    pages = []
    page_keys = ['page1', 'page2']
    for obj, name in zip([urlc, ipc], page_keys):
        paginator = Paginator(obj, 20)
        page = self.request.GET.get(name)
        page_ipc = obj
        try:
            page_ipc = paginator.page(page)
        except PageNotAnInteger:
            page_ipc = paginator.page(1)
        except EmptyPage:
            page_ipc = paginator.page(paginator.num_pages)
        pages.append(page_ipc)

    context['data'] = zip(pages, page_keys)
    return context
2.自定义子
模板
。 我们定义了一些变量,以便可以遍历分页列表

pagination.html

    {% if is_paginated %}
        <ul class="pagination">
        {% if page_obj.has_previous %}
            <li>
            <span><a href="?{{ pname }}={{ 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="?{{ pname }}={{ page_obj.next_page_number }}">Next</a></span>
            </li>
        {% endif %}
        </ul>
    {% else %}
        <h3>Your File Exam</h3>
        <p>File not yet available</p>
    {% endif %}
{% for foo,name in data %}
    <div class="col-md-3 table-responsive">

            {% for k,v in foo %}
                <tr>
                    <th>{{ forloop.counter }}</th>
                    <td>{{ k }}</td>
                    <td>{{ v }}</td>
                </tr>
            {% endfor %}

        {% include 'pagination.html' with pname=name  page_obj=foo %}
    </div>
{% endfor %}

没关系,但是如何将模板也绑定到“car\u list”对象?仅供参考,您也可以直接在url.py:url(r'^cars/$,ListView.as\u view(model=car,paginate\u by=10))中执行此操作,我学到的教训是:要找到一个方法,请在新选项卡中打开所有祖先类,然后按住CTRL+F键,去掉关键字。因此,我们从基础教程中了解到,从中,打开所有祖先链接并搜索“pagi”我一直在这样做,但我发现的问题是,当我对queryset中的对象进行额外处理时,它会将它们应用于数据库中的所有结果。因此,对于一个返回100个对象,但每页仅显示10个对象的查询,额外的处理将对100个对象进行。我不喜欢可以用以下内容替换的硬编码URL:this看起来不对:
context=super(SoalListView,self).
。您的意思是:
context=super(FileExamListView,self)…
?是的,对!这个答案是由Yacin先生编辑的。谢谢你,Yacin先生。根据我的测试,我们不能像你那样截获
PageNotAnyTeger
异常,因为如果我们通过
GET
参数传递一个非整数,
ValueError
异常将在
PageNotAnyTeger
异常之前引发这发生在
ListView
类的
paginate\u queryset
方法的级别。希望这是清楚的