关键词

详解Django的 paginate_orphans() 函数:指定一页最少显示的对象数量

Django的paginate_orphans()函数详解

paginate_orphans()函数是Django框架中pagination(分页)模块的一部分。其作用是用来确定在一个分页显示中的一页中最少要显示的记录数量。当一页中只有“孤儿”记录时,可以将它们作为上一页的最后一页来显示,以免摆在一页中的孤儿记录过少而显得过于孤立。

使用方法:

class CustomPaginator(Paginator):
    def __init__(self, orphans=0, *args, **kwargs):
        self.orphans = orphans
        super(CustomPaginator, self).__init__(*args, **kwargs)

    def _get_page(self, *args, **kwargs):
        page_number = kwargs.pop('page_number', 1)
        if page_number in self._pages:
            return self._pages[page_number]
        if page_number > self.num_pages:
            if hasattr(self.object_list, 'count') and \
                    self.object_list.count() > 0:
                raise EmptyPage(_('That page contains no results'))
            else:
                raise EmptyPage(_('That page contains no results'))
        bottom = (page_number - 1) * self.per_page
        top = bottom + self.per_page + self.orphans - 1
        if top >= self.count:
            top = self.count - 1
        self._check_object_list_is_ordered()
        page = self._get_page_from_object_list(self.object_list[bottom:top + 1], *args, **kwargs)
        if self.orphans and self.count - top - 1 < self.orphans and \
                page.has_previous():
            top = self.count - self.orphans - self.per_page - 1
            bottom = top - self.per_page + 1
            page = self._get_page_from_object_list(self.object_list[bottom:top + 1], *args, **kwargs)
        self._pages[page_number] = page
        return page

其中orphans参数默认为0,代表每一页都至少需要显示一定数量的数据,也就是不被视为“孤儿记录”的数据量。如果某一页显示的数据量少于设定的orphans值,那么这些“孤儿记录”会在分页显示中被自动分配到上一页的最后一页,以保持页面显示的整洁性。

接下来给出两个实例来说明该函数的作用与使用方法:

实例一

假设我们的业务需求是在一个友链页面上展示多个友情链接,每页只展示3个链接信息,需要保证每一页至少展示2个链接信息。

使用上述的CustomPaginator类及paginate_orphans设置为2进行友链列表数据的分页:

from django.core.paginator import EmptyPage, Paginator
from django.views.generic import ListView
class FriendLinkView(ListView): 
    template_name = 'friend_link.html'
    model = FriendLink
    paginate_by = 3

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        orphans = 2  # 每一页需要至少有 2 个记录
        paginator = CustomPaginator(orphans=orphans, object_list=self.get_queryset(), per_page=self.paginate_by)
        page = self.request.GET.get('page')

        try:
            friend_link_list = paginator.page(page)
        except EmptyPage:
            friend_link_list = paginator.page(paginator.num_pages)

        context['friend_link_list'] = friend_link_list
        return context

当FriendLink表中的记录有4条时,需要分两页展示,则实现效果如下图所示:

可以看到第一页有3个友链信息,第二页只有1个友链信息,但由于设定的orchans值为2,所以第一页只有2个链接的显示,第3个友链信息自动分配到第二页上,保证了页面显示的整洁性。

实例二

使用paginate_orphans()函数可以方便地设置分页显示的规则,可以根据具体的需求来设置。

例如,我们有一个博客网站,需要在分类页面上分页展示博文列表,每一页最多只能显示10篇文章,但需要保证每一页至少会展示出两篇文章。那么我们可以使用:

from django.core.paginator import EmptyPage, Paginator
from django.views.generic import ListView

class BlogListView(ListView):
    template_name = 'blog_list.html'
    model = Blog
    paginate_by = 10

    def get_context_data(self, **kwargs):
        context = super(BlogListView, self).get_context_data(**kwargs)
        orphans = 2  # 每一页需要至少有 2 篇文章
        blog_list = self.get_queryset()
        paginator = Paginator(blog_list, self.paginate_by, orphans=orphans)
        page = self.request.GET.get('page')
        try:
            blogs = paginator.page(page)
        except EmptyPage:
            blogs = paginator.page(paginator.num_pages)
        context['blogs'] = blogs
        return context

这个例子与实例一相似,只需要改变model类和template_name即可。下图是展示效果:

可以看到,第一页只展示了8篇文章,第二页展示了7篇文章,但是由于它们少于设置中的“至少有两篇文章”,系统自动将它们视为孤儿,将这些文章挤到了上一页中展示,保证了整个分页的整洁性。

本文链接:http://task.lmcjl.com/news/16246.html

展开阅读全文