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

时间:2011-05-06 06:25:49

标签: django

如何使用Django 1.3分页?

文档不是很清楚。

  • views.py的内容是什么?

  • 我的模板有什么用?

  • 我的URLconf文件是什么?

3 个答案:

答案 0 :(得分:322)

我认为您要求提供有关使用基于新类的视图分页的信息,因为使用传统的基于函数的视图,很容易找到。我发现只需设置paginate_by变量即可激活分页。请参阅 Class-based generic views

例如,在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 !!

在您的模板(car_list.html)中,您可以添加这样的分页部分(我们有一些可用的上下文变量:is_paginatedpage_objpaginator)。

{# .... **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.** .... #}

要显示的页面由GET参数指示,只需将?page=n添加到网址即可。

答案 1 :(得分:37)

假设我在app / models.py中有一个名为public class Sticker { public int x, y; public EZImage picture; public EZSound sounds; public String picName; Sticker(String image, String sound, int xPosition, int yPosition){ picture = EZ.addImage(image, xPosition, yPosition); sounds = EZ.addSound(sound); x = xPosition; y = yPosition; picName = image; } Sticker(String name, int somex, int somey){ picture = EZ.addImage(name, somex, somey); x = somex; y = somey; } } 的课程:

应用/ models.py

FileExam(models.Model)

应用/ 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(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 只有一点点变化,并添加了来自django文档here的分页代码

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

正常内容列表

get_context_data

分页部分

<table id="exam">
  {% for exam in list_exams %}
  <tr>
    <td>{{ exam.myfile }}</td>
    <td>{{ exam.date }}</td>
    <td>.....</td>
  </tr>
  {% endfor %}
</table>

应用/ urls.py

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

答案 2 :(得分:1)

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

第一个很简单,只需设置类字段paginate_by。我们不需要使用get_context_data方法。

第二种方法有些复杂,但是我们可以对分页有更多的了解,并可以定制复杂的分页或几种分页。让我们看看吧。

可以通过三个步骤完成。

1。覆盖get_context_data的{​​{1}}方法。

传递Viewpage_keys,以便我们可以迭代列表并避免进行硬编码。

pages

2。自定义您的子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

我们定义了一些变量,以便我们可以遍历分页列表。

template

pagination.html

3。自定义外部 {% 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 %}

template

index.html