Django 分页操作


1.在每个需要分页的函数和模板加入分页代码

情况:每个页面除了分页外还需要使用其他参数,如分类、排序等,不建议使用一个封装的库来实现分页。
步骤1:在需要分页的views中加入如下代码:

from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage # 分页需要的库
#以下是分页的例子
def user_mycourse(request):
    mycourse=UserCourse.objects.filter(study_man=request.user)
    courses=[course.study_course for course in mycourse]
    #这是分页需要写的代码,尽量不要动这些代码的名称,只需将要分页的内容与文中的courses替换,8为每页的数据数,除此之外不需要改动
    pagenum = request.GET.get('pagenum', '')
    pa = Paginator(courses, 8)
    try:
        pages = pa.page(pagenum)
    except PageNotAnInteger:
        pages = pa.page(1)
    except EmptyPage:
        pages = pa.page(pa.num_pages)
    return render(request,'users/usercenter-mycourse.html',{'courses':courses,'pages':pages,'type':'course'}) #将pages传入模板渲染

步骤2:在模板中添加如下HTML代码

#原来的循环返回所有数据
{% for course in courses %}
#将其改为
{% for course in pages %}

#在分页的地方添加代码
    {% if pages.has_previous %}
  • 上一页
  • {% endif %} {% for number in pages.paginator.page_range %} {% if number == pages.number %}
  • {{ number }}
  • {% else %}
  • {{ number }}
  • {% endif %} {% endfor %} {% if pages.has_next %}
  • 下一页
  • {% endif %}

这样一个只有分页的分页器就完成了,但很多情况下网站需要在分页的时候排序和分类,此时在views需要将排序、分类的代码写在分页代码之前,而且需要将排序
分类的值传回去以便分页时仍然保存排序、分类

def course_list(request):
    all_courses=CourseInfo.objects.all().order_by('-add_time')
    sort_courses=all_courses.order_by('-love_num')[:3]
    sort='add_time'
    #分类、排序的操作必须写在分页之前,最好还是使用原来的列表来实现操作。
    sort =request.GET.get('sort')
    if not sort:
        sort='add_time'
    pagenum = request.GET.get('pagenum', '')
    keywords = request.GET.get('keywords', '')
    if keywords:
        all_courses = all_courses.filter(
            Q(name__icontains=keywords) | Q(desc__icontains=keywords) | Q(detail__icontains=keywords))
    if sort:
        all_courses=all_courses.order_by('-'+sort)
    pa = Paginator(all_courses,9)
    try:
        pages = pa.page(pagenum)
    except PageNotAnInteger:
        pages = pa.page(1)
    except EmptyPage:
        pages = pa.page(pa.num_pages)
    #记住将排序、分类值传入模板,否则分页时会没有排序和分类
    return render(request,'courses/course-list.html',{'all_courses':all_courses,'sort_courses':sort_courses,'base_type':'course','sort':sort,'pages':pages,'keywords':keywords})

相对应的html也需要发生变化

   
    {% if pages.has_previous %}
  • 上一页
  • {% endif %} {% for number in pages.paginator.page_range %} {% if number == pages.number %}
  • {{ number }}
  • {% else %}
  • {{ number }}
  • {% endif %} {% endfor %} {% if pages.has_next %}
  • 下一页
  • {% endif %}

这样即可完成带其他参数的分页操作

**2.如果很多页面只需要简单的分页而没有其他参数时,或者其他参数一致时,可以将分页封装成包来使用

from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage
class Page(Paginator):
    def __init__(self, request,object_list,per_page):
        Paginator.__init__(self, object_list, per_page, orphans=0,
                 allow_empty_first_page=True)
        #data 为传输的分页内容,per_page为每页显示的内容
        pagenum = request.GET.get('pagenum', '')
        pa = Paginator(object_list,per_page)
        try:
            pages = pa.page(pagenum)
        except PageNotAnInteger:
            pages = pa.page(1)
        except EmptyPage:
            pages = pa.page(pa.num_pages)
        page_list=['
    '] if pages.has_previous(): page_list.append('
  • 上一页
  • '.format(pages.previous_page_number)) for number in pages.paginator.page_range: if number ==pages.number: page_list.append('
  • {}
  • '.format(number,number)) else: page_list.append('
  • {}
  • '.format(number,number)) if pages.has_next(): page_list.append('
  • 下一页
  • '.format(pages.next_page_number)) page_list.append('
') self.page_html = ''.join(page_list) self.pages=pages

要使用时只需要将函数导入所需要的views中

  
 #分页功能
    #只需要将需要分页的列表替换all_orgs,每页的数据量替换3即可
    page=Page(request,all_orgs,3)
   #返回时需要返回'pages':page.pages,'page_html':page.page_html
    return render(request,'orgs/org-list.html',{'all_orgs':all_orgs,'pages':page.pages,'page_html':page.page_html})

在对应的HTML中加入一行代码即可

#原来的循环返回所有数据
{% for course in courses %}
#将其改为
{% for course in pages %}
#在分页的地方只需添加即可
{{ page_html|safe }}