Django 之 Paginator 分页功能

Django Paginator

Django 分页官方文档  https://docs.djangoproject.com/en/1.10/topics/pagination/

 此分页方法没有限制显示出来的页码的个数,会显示全部的页码,待改进。

后端代码

由于代码是先object_list = model_obj.model.objects.all(),然后调用 paginator = Paginator(object_list, 2),如果数据量很大就会消耗很多的性能。

如果是这样呢写呢? paginator = Paginator(model_obj.model.objects.all(), 2)  这样能利用queryset的惰性机制吗? 

看了下Paginator源码,应该是可行的
 1 class Paginator(object):
 2 
 3     def __init__(self, object_list, per_page, orphans=0,
 4                  allow_empty_first_page=True):
 5         self.object_list = object_list
 6         self.per_page = int(per_page)
 7         self.orphans = int(orphans)
 8         self.allow_empty_first_page = allow_empty_first_page
 9 
10     def validate_number(self, number):
11         """
12         Validates the given 1-based page number.
13         """
14         try:
15             number = int(number)
16         except (TypeError, ValueError):
17             raise PageNotAnInteger('That page number is not an integer')
18         if number < 1:
19             raise EmptyPage('That page number is less than 1')
20         if number > self.num_pages:
21             if number == 1 and self.allow_empty_first_page:
22                 pass
23             else:
24                 raise EmptyPage('That page contains no results')
25         return number
26 
27     def page(self, number):
28         """
29         Returns a Page object for the given 1-based page number.
30         """
31         number = self.validate_number(number)
32         bottom = (number - 1) * self.per_page
33         top = bottom + self.per_page
34         if top + self.orphans >= self.count:
35             top = self.count
36         return self._get_page(self.object_list[bottom:top], number, self)
37 
38     def _get_page(self, *args, **kwargs):
39         """
40         Returns an instance of a single page.
41 
42         This hook can be used by subclasses to use an alternative to the
43         standard :cls:`Page` object.
44         """
45         return Page(*args, **kwargs)
46 
47     @cached_property
48     def count(self):
49         """
50         Returns the total number of objects, across all pages.
51         """
52         try:
53             return self.object_list.count()
54         except (AttributeError, TypeError):
55             # AttributeError if object_list has no count() method.
56             # TypeError if object_list.count() requires arguments
57             # (i.e. is of type list).
58             return len(self.object_list)
59 
60     @cached_property
61     def num_pages(self):
62         """
63         Returns the total number of pages.
64         """
65         if self.count == 0 and not self.allow_empty_first_page:
66             return 0
67         hits = max(1, self.count - self.orphans)
68         return int(ceil(hits / float(self.per_page)))
69 
70     @property
71     def page_range(self):
72         """
73         Returns a 1-based range of pages for iterating through within
74         a template for loop.
75         """
76         return six.moves.range(1, self.num_pages + 1)
77 
78 
79 QuerySetPaginator = Paginator   # For backwards-compatibility.
Paginator 部分源码

#需要导入 的模块
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 


def display_table_objs(request,app_name,table_name):
    print(app_name,'----',table_name)
    #获取数据库数据
    model_obj = king_admin.enabled_admins[app_name][table_name]

    #分页
    object_list = model_obj.model.objects.all()
    paginator = Paginator(object_list, 2)  # Show 2 contacts per page
    # paginator = JuncheePaginator(object_list, 1)  # Show 2 contacts per page

    page = request.GET.get('page')
    try:
        contacts = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        contacts = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        contacts = paginator.page(paginator.num_pages)

    return render(request,'king_admin/table_objs.html',{"model_obj":model_obj,
                                                        "query_sets":contacts,})

 

前端模板代码

其中的标签样式引用的Bootstrap的样式

 <ul class="pagination">
                    {# topics.paginator.page_range 这个函数返回包含一个所有页码数的 range 对象 #}
                    {# 即 range(1, topics.paginator.num_pages + 1) #}
                    {% if query_sets.has_previous %}
                        <li><a href="?page={{ query_sets.previous_page_number }}">上一页</a></li>
                    {% else %}
                        <li><span>没了</span></li>
                    {% endif %}
                    {% for page_number in query_sets.paginator.page_range %}

                        {% ifequal page_number  query_sets.number %}
                            <li class="disabled"><span>{{ page_number }}</span></li>

                        {% else %}
                            <li ><a href="?page={{ page_number }}">{{ page_number }}</a></li>

                        {% endifequal %}
                    {% endfor %}

                    {% if query_sets.has_next %}
                        <li><a href="?page={{ query_sets.next_page_number }}">下一页</a></li>
                    {% else %}
                        <li><span>没了</span></li>
                    {% endif %}
                </ul>

 

效果如下:

 

posted @ 2017-01-09 12:59  noube  阅读(538)  评论(0编辑  收藏  举报