django中提供便捷的分页服务,主要通过
Pagination来实现的,详细可以参考Django文档,通过简单设立每页显示的数量,来自动化获得分页object_list,先来看看调用方式,借用文档里面的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| >>> from django.core.paginator import Paginator >>> objects = ['john', 'paul', 'george', 'ringo'] >>> p = Paginator(objects, 2) >>> p.count 4 >>> p.num_pages 2 >>> p.page_range [1, 2] >>> page1 = p.page(1) >>> page1 <Page 1 of 2> >>> page1.object_list ['john', 'paul']
>>> page2 = p.page(2) >>> page2.object_list ['george', 'ringo'] >>> page2.has_next() False >>> page2.has_previous() True >>> page2.has_other_pages() True >>> page2.next_page_number() Traceback (most recent call last): ... EmptyPage: That page contains no results
|
其实分页并不是一个复杂的流程,但是我跟喜欢使用官方提供的功能,省的自己浪费没有必要的时间,但是在使用的过程中,还是优点满足不了我们的用途,一般写导航的时候都会显示当前页前后3-4也的导航,向这样的:
![导航][2]
而我们仅仅能得到一个所有的列表,加之每次都要在模板里配置嫌多判断,前不久学习了一种好的写法,稍微改造了下,封装了下,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| def my_pagination(request, queryset, display_amount=15, after_range_num = 5,bevor_range_num = 4): paginator = Paginator(queryset, display_amount) try: page =int(request.GET.get('page')) except: page = 1 try: objects = paginator.page(page) except EmptyPage: objects = paginator.page(paginator.num_pages) except: objects = paginator.page(1) if page >= after_range_num: page_range = paginator.page_range[page-after_range_num:page+bevor_range_num] else: page_range = paginator.page_range[0:page+bevor_range_num] return objects,page_range
|
在模板中配套加入代码,这个模板使用bootstrap应该很好理解
分页出来的数据处理,像这样写
1 2 3 4 5 6 7
| {% if objects.object_list %} {% for p in objects.object_list %} ... {% endfor %} {% else %} ... {% endif %}
|
然后在下面加入导航
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <div class="pagination pagination-centered"> <ul> {% if objects.has_previous %} <li><a href="?page={{ objects.previous_page_number }}">前一页</a></li> {% else %} <li class="active"><a>前一页</a></li> {% endif %}
{% for p in page_range %} {% ifequal p objects.number %} <li class="active"><a>{{p}}</a></li> {% else %} <li><a href="?page={{p}}" title="第{{p}}页">{{p}}</a><li> {% endifequal %} {% endfor %}
{% if objects.has_next %} <li><a href="?page={{ objects.next_page_number }}">后一页</a></li> {% else %} <li class="active"> <a>后一页</a></li> {% endif %} </ul> </div>
|
大家可能还关心view怎么写,给一个简单的示例吧:
1 2 3 4
| def my_view(request): all_objects = some_model.objects.all() objects, page_range = my_pagination(request, all_objects) return render_to_response('a_template.html',{'objects':objects,'page_range':page_range},context_instance=RequestContext(request))
|
简单来说下这样写的好处,一方面不用关心处理的逻辑,一方面不需要对模板进行特殊处理,将request传进去,连page参数都不用操心,相信这样的一个分页函数能帮到你!