Py学习  »  Django

[精华] 七步教你实现Django网站列表自动分页

Py站长 • 10 年前 • 61693 次点击  

网站,特别是论坛,就如本社区一样,肯定会遇到某个页面要显示列表(比如本社区的首页,要显示主题列表),那肯定就会涉及到列表的分页功能。

举个例子,比如一个列表有100个item,那我们网站的页面是不是将此100个item都显示出来吗?显示不是哦,这样做以后一来是页面不好看(页面太长啦),用户体验不好(用户根本不需要看这么多item);第二就是性能不好(一下子读取这么多item,网站肯定很吃力 啊)。

废话就不说啦,今天将要介绍一下Django的分页利器APP--- django-pagination,它可以非常方便的为你实现你的分页目标!我将结合 本社区的实现方式来介绍。

项目主页: https://github.com/ericflo/django-pagination/

本社区使用它来进行各种列表的分页。

介绍:

django-pagination allows for easy Digg-style pagination without modifying your views.

django-pagination就像它的名字一样,它是一个Django分页器,它包含了一组翻页功能相关的utils,包括用于实现翻页的tag等。使用起来非常简单。是目前使用最多的分页APP。

如何使用:

总共有七步来实现:

  1. 安装

    sudo python setup.py install

  2. 将该APP安装至Django项目中。(请修改settings.py)

     INSTALLED_APPS = (
           # ...
           'pagination',
       )
    
  3. 在Django项目的middleware中安装此APP:(请修改settings.py)

     MIDDLEWARE_CLASSES = (
           # ...
           'pagination.middleware.PaginationMiddleware',
       )
    

    这样,django-pagination可以在页面请求过程中做一些简单的处理。

  4. 请确保你的请求上下文含有django.core.context_processors.request。 如果没有的话,请将django.core.context_processors.request加入到 TEMPLATE_CONTEXT_PROCESSORS中,示例如下:(请修改settings.py)。

    ("django.core.context_processors.auth",
        "django.core.context_processors.debug",
        "django.core.context_processors.i18n",
        "django.core.context_processors.media",
        "django.core.context_processors.request")
    
  5. 在你要进行列表分页的页面(template)的页面上方(最好是最上面)中 导入 它的tag, 以便后续我们可以在模板中使用它的一些功能。

     {% load pagination_tags %}
    
  6. 在你的模板(template)页面上,对你想要分页的列表变量(object_list)进行分页,在模板中写如下代码:(这段短代码的位置要在 放在 你显示 object_list 之前)

    {% autopaginate object_list %}
    

    上面对列表分页后默认每页有20个,如果你想自己自定义,可以这样:

    {% autopaginate object_list 10 %}
    

    这样对列表分页后每页显示10个。

    分页后,django-pagination会更改object_list 的值,将object_list 变成一个只有20个(默认情况下)的列表。你可以对object_list 进行遍历,显示出他们。

    经过此步后,大家就可以获取得到只有一页的列表啦。

  7. 经过上步,我们得到一页列表啦,但是我们想要第二页,第三页……,最好是在每一页的最底部有一个页数导航栏可以供大家选择。例如:

    方法很简单。只要在页面的最底下使用如下代码:

    {% paginate %}
    

    当然,页数导航栏使用的UI模板是 pagination/templates/pagination/pagination.html ,我们需要按我们站点的UI美观需要来更改它哦。

小结:

怎么样,使用django-pagination后,大家肯定会觉得:“哇,太好用啦”,什么事都帮我们做啦。是不是非常方便呢? :)

关于性能:

还有一个问题没有解决哦,因为肯定有朋友会问,如果一个列表有100000个item, 我们想要实现每页40个,那么,当将我们请求该列表时, django-pagination在分页过程中,请求数据库是取40个,还是取100000啊!

显然,django-pagination是不可能取100000的啦。

django-pagination 巧妙的利用了Django延迟获取数据的特性,因此,django-pagination每次取数据都是只取每页的数据的(也就是上例中的40个),所以是不会有性能 影响 的哦。

关于这个问题,作者的主页有两个视频解释:(英文视频,E文可以的同学可以看看)

http://eflorenzano.com/blog/2008/07/12/first-two-django-screencasts/

最后:

最后面,请大家要支持Django中国社区哦,单靠一两个人是不行的,一起推广一下,让Django社区更有力量哈!更有人气哈!

推广链接: http://django-china.cn/

END

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/53
 
61693 次点击  
文章 [ 46 ]  |  最新文章 8 年前
WildCat
Reply   •   1 楼
WildCat    10 年前

@Django中国社区 我这里是1.4.报错:

KeyError at /

'request'

Request Method: GET Request URL: http://localhost:8000/ Django Version: 1.4.5 Exception Type: KeyError Exception Value:

'request'

Exception Location: D:\Python27\lib\site-packages\django\template\context.py in getitem, line 54 Python Executable: D:\Python27\python.exe Python Version: 2.7.4 Python Path:

['F:\ASWorkspace\daxuanwo', 'D:\Program Files\Aptana Studio\plugins\org.python.pydev_2.7.0.2013012902\pysrc', 'F:\ASWorkspace\daxuanwo', 'D:\Python27\DLLs', 'D:\Python27\lib', 'D:\Python27\lib\plat-win', 'D:\Python27\lib\lib-tk', 'D:\Python27', 'D:\Python27\lib\site-packages', 'C:\Windows\system32\python27.zip', 'D:\Python27\lib\site-packages\PIL']

Server time: 星期一, 24 六月 2013 10:47:25 +0800

Py站长
Reply   •   2 楼
Py站长    10 年前

@BeginMan 你可以试试1.4, 如果解决了,就是版本的问题了

BeginMan
Reply   •   3 楼
BeginMan    10 年前

难道是版本的问题吗,我的是1.2.3,弄了两个多小时,还是出不来,崩溃了都。

放置正确

INSTALLED_APPS:已添加

TEMPLATE_CONTEXT_PROCESSORS :已添加

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",  
    "django.core.context_processors.debug",  
    "django.core.context_processors.i18n",  
    "django.core.context_processors.media",  
    "django.core.context_processors.request"  
)

中间件已添加: 'pagination.middleware.PaginationMiddleware',

页面已添加:

{% extends "base.html"%}
{% load pagination_tags %}
{% autopaginate contents 3 %}
{% block title %}新闻动态{% endblock %}
{% block content %}
    <ul class="breadcrumb">
    <li><i class="icon-th-large">&nbsp;</i><strong>&nbsp;新闻动态</strong> <span class="divider">/</span></li>
    <li class="active">&nbsp;&nbsp;&nbsp;News</li>
    </ul>
    {% for obj in contents %}
    <div class="breadcrumb" style="background:#F7F7F9">
    <a href="/news/{{obj.id}}/" target="_blank"><p><span class="badge badge-warning">{{obj.id}}</span>&nbsp;&nbsp;{{obj.title}}<span style="float:right; color:#999999">{{obj.time|date:"Y-m-d H:i"}}</span></p></a>
    </div>
    {% endfor %}
    <!-- 分页 -->
    {% paginate %}
{% endblock %}

view已添加:

def news_list(request):
    contents = New.objects.all()
    return render_to_response('news_list_page.html',{'contents':contents})

但是还是没效果,如下:

enter image description here

求助啊!!

一休哥
Reply   •   4 楼
一休哥    10 年前

看来用1.5.1版本还有诸多不便啊。。

爱情的枪
Reply   •   5 楼
爱情的枪    10 年前

不错啊,支持一下

Py站长
Reply   •   6 楼
Py站长    10 年前

@易冷天涯 也是个不错的方法,赞!

易冷天涯
Reply   •   7 楼
易冷天涯    10 年前

在看到@枫若水漪 说1.5.1版本没法用这个分页工具后,我没有去尝试用这个分页工具分页,因为我的环境也是1.5.1版本。

我参考了了@BeginMan 博客中的方法为我的一个页面分页。暂时用下面的代码实现:

<table>
        <tr>
            {% if posts.has_previous %}
            <td><a href="?page={{ posts.previous_page_number }}">上一页 </a></td>
            {% endif %}
            {% if posts.has_next %}
            <td><a href="?page={{ posts.next_page_number }}">下一页</a></td>
            {% endif %}
            <td>{{ posts.number }} 页,共 {{ posts.paginator.num_pages }}</td>
            <form action="." method="get">
            <td>到第</td>
            <td><input name="page" type="text" ></td>
            <td></td>
            <td><input type="submit" value=" 跳转 "></td>
            </form>
        </tr>
</table>

效果如图: enter image description here

Py站长
Reply   •   8 楼
Py站长    10 年前

@枫若水漪 也有可能,我用的是1.4.2版本

枫若水漪
Reply   •   9 楼
枫若水漪    10 年前

@Django中国社区 我的django版本是1.5.1的

枫若水漪
Reply   •   10 楼
枫若水漪    10 年前

@Django中国社区 view.py 应该没问题,不分页很正常,是不是版本问题,django2.0的setting里面没有TEMPLATE_CONTEXT_PROCESSORS这个。

Py站长
Reply   •   11 楼
Py站长    10 年前

@艾莉柯_李 没试过,不过应该可以的

艾莉柯_李
Reply   •   12 楼
艾莉柯_李    10 年前

sae能用不?

zhwei
Reply   •   13 楼
zhwei    10 年前

@枫若水漪 我上次碰到这个问题是因为TEMPLATE_CONTEXT_PROCESSORS没有修改

Py站长
Reply   •   14 楼
Py站长    10 年前

@枫若水漪 你把你的view.py代码贴出来看看~~ 我估计是你的view代码写错了

枫若水漪
Reply   •   15 楼
枫若水漪    10 年前

@Django中国社区 Exception Type: KeyError Exception Value: 'request' Exception Location: C:\Python27\lib\site-packages\django\template\context.py in getitem, line 57 这个样子,怎么办

枫若水漪
Reply   •   16 楼
枫若水漪    10 年前

@Django中国社区 加过了,还是会报错,而且admin也会报错。 没有第四步过不去啊。。不做第四步一直过不去,一直反request的错误

Py站长
Reply   •   17 楼
Py站长    10 年前

@枫若水漪 那你添加一个 TEMPLATE_CONTEXT_PROCESSORS 配置 看看?

枫若水漪
Reply   •   18 楼
枫若水漪    10 年前

第四步怎么做?我的settings.py里面没有 TEMPLATE_CONTEXT_PROCESSORS

zhwei
Reply   •   19 楼
zhwei    10 年前

模板放置路径
{{your_templates}}/pagination/pagination.html

indexofire
Reply   •   20 楼
indexofire    10 年前

我推荐一个app: django-endless-pagination