Django Web 开发实战

文章分页功能

文章多起来了,我们就需要一个分页功能了,像这样:

如何添加上这个功能呢?Django自带有分页功能的,但我们这里使用一个处理分页的第三方插件linaro-django-pagination

安装方法

$ pip install linaro-django-pagination

设置

插件的设置是在settings.py中进行的,我们进行以下设置:

1.添加到INSTALL_APP,像这样:

INSTALLED_APPS = (
    # ...
    'linaro_django_pagination',
)

2.安装中间件:

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

3.设置TEMPLATE_CONTEXT_PROCESSORS

这里需要注意一下,Django 1.6之后,在settings.py已没有这一项了,而只作为了一个默认设置项存在的,你可以Shell中查看认项:

In [1]: from django.conf import settings
In [2]: settings.TEMPLATE_CONTEXT_PROCESSORS
Out[2]:
('django.contrib.auth.context_processors.auth',
 'django.core.context_processors.debug',
 'django.core.context_processors.i18n',
 'django.core.context_processors.media',
 'django.core.context_processors.static',
 'django.core.context_processors.tz',
 'django.contrib.messages.context_processors.messages')

需要注意的是.media.static这两项。如果你安照linaro-django-pagination文档设置的话,你会发现,你的静态文件无法被浏览器解析了。原因是模版中使用到的参数{{ STATIC_URL}}没有被传递进去,所以.static这项是必须添加上的。

在这里,你需要添加上:

"django.core.context_processors.request",

4.设置每页显示项数

关于显示项目,可以有两个地方进行设置,一是在settings.py中,二是在模版文件中,方式分别为:

## settings.py

PAGINATION_DEFAULT_PAGINATION = 2 # 默认值是20

## 在模版中

{% autopaginate object_list 10 %}

由于我们模版就一个地方使用到分页,所以我们就直接放到settings.py中。暂时设置为每页两项,主要是为了调试样式之类,等开发完成,再行修改即可。

使用

使用是在模版中进行的,分三步:

第一步,载入插件:

{% load pagination_tags %}

第二步,添加自动分页到项目遍历之前:

{% autopaginate posts %}

第三步,显示分页:

在你想要显示的地方,一般为整个项目遍历完成的地方:

{% paginate %}

整个代码如下:

{% extends "base.html" %}
{% load pagination_tags %}

{% block title %}{% if is_category %}“{{ cate_name|safe }}”文章列表{% else %}首页{% endif %}{% endblock %}
{% block content %}
{% if is_category %}
<div class="well well-sm">
    “{{ cate_name|safe }}”分类中共有
    <span class="label label-info">{{ posts|length}}</span>篇:
</div>
{% endif %}
{% autopaginate posts %}
{% for post in posts %}
{% include "blog/_post.html" %}
{% endfor %}
{% paginate %}
{% endblock %}

{% block rightside %}
{% include "blog/_side.html" %}
{% endblock %}

然后我们就可以看到分页了。

如何自定义分页样式

尽管我们看到了分页,而且也能正常使用的,但和我们的CSS样式不太配合得起来,因为我们可以自己重新来调整一下,使用自定义的模版,只需要在templates/下创建一个与插件模版相同的目录及文件名就行了。最简单的办法就是直接从插件中复制到我们的项目目录中来,然后再生新调整即可。

templates/pagination/pagination.html内容为:

{% if is_paginated %}
{% load i18n %}
<ul class="pagination">
  {% block previouslink %}
  {% if page_obj.has_previous %}
  <li><a href="?page{{ page_suffix }}={{ page_obj.previous_page_number }}{{ getvars }}" class="prev">{{ previous_link_decorator|safe }}{% trans "previous" %}</a></li>
  {% else %}
  {% if display_disabled_previous_link %}
  <li><span class="disabled prev">{{ previous_link_decorator|safe }}{% trans "previous" %}</span></li>
  {% endif %}
  {% endif %}
  {% endblock previouslink %}
  {% block pagelinks %}
  {% if display_page_links %}
  {% for page in pages %}
  {% if page %}
  {% ifequal page page_obj.number %}
  <li><span class="current page">{{ page }}</span></li>
  {% else %}
  <li><a href="?page{{ page_suffix }}={{ page }}{{ getvars }}" class="page">{{ page }}</a></li>
  {% endifequal %}
  {% else %}
  <li>...</li>
  {% endif %}
  {% endfor %}
  {% endif %}
  {% endblock pagelinks %}
  {% block nextlink %}
  {% if page_obj.has_next %}
  <li><a href="?page{{ page_suffix }}={{ page_obj.next_page_number }}{{ getvars }}" class="next">{% trans "next" %}{{ next_link_decorator|safe }}</a></li>
  {% else %}
  {% if display_disabled_next_link %}
  <li><span class="disabled next">{% trans "next" %}{{ next_link_decorator|safe }}</span><li>
  {% endif %}
  {% endif %}
  {% endblock nextlink %}
</ul>
{% endif %}

当然你可以根据自己的需要进行调整。