文档章节

Django原生sql也能使用Paginator分页

张豪飞
 张豪飞
发布于 2017/11/14 17:28
字数 689
阅读 107
收藏 5
点赞 1
评论 0

0x00 Django分页局限

使用Django肯定经常使用Paginator分页,很便捷。但是他可接受的分页对象必须是django orm的查询集或者list、tuple。

当需要使用原生sql查询数据且分页就无法使用Paginator。

0x01 分页原理

其实分页就是传入数据集、每页数量、当前页数,然后计算(查询)数据总数量,根据每页数量计算出总页数,当前页的开始index和结束index,然后根据开始index结束index获取本页数据返回。

请注意上面一句话的黑体字部分,它们就是计算分页的核心,那么Paginator其实只需要实现两个方法count__getslice__就可以自定义一个让Paginator支持的对象,然后就可以使用Paginator分页了,不需要单独对原生sql写分页逻辑

0x02 自定义分页

# coding=utf-8

from django.core.paginator import Paginator


def paginator(data_list, per_page, page_no):
    """封装Django分页"""
    pages = Paginator(data_list, per_page)

    # 防止超出页数
    if not page_no > 0:
        page_no = 1
    if page_no > pages.num_pages:
        page_no = pages.num_pages

    p = pages.page(page_no)  # 获取本页数据

    data = dict()  # 获取分页信息
    data['count'] = pages.count
    data['page_num'] = pages.num_pages
    data['per_page'] = per_page
    data['current'] = page_no
    data['start_index'] = p.start_index() - 1

    return p.object_list, page_no, data


class QueryWrapper(object):
    """查询集包装器。实现django Paginator需要的必要方法,实现和query一样使用Paginator分页"""

    def __init__(self, sql, params=None, db="default"):
        """
        :param sql: sql语句
        :param params: sql语句的params参数
        :param db: 数据库名称(Django配置)
        """
        self.db = db
        self.sql = sql
        self.params = params

    def count(self):
        """计算总页数"""
        sql = """select count(*) from (%s) _count""" % self.sql
        # sql封装方法请参考https://my.oschina.net/watcher/blog/1573503
        return fetchone_sql((sql, self.params), db=self.db, flat=True)  # 返回总页数

    def __getslice__(self, x, y):
        """ self.__getslice(x, y) = self[x:y]"""
        sql = self.sql + ' LIMIT {start}, {num}'.format(start=x, num=y - x)
        # sql封装方法请参考https://my.oschina.net/watcher/blog/1573503
        return fetchall_to_dict((sql, self.params), db=self.db)  # 字典列表形式返回


def demo_orm():
    """使用Django的ORM分页"""
    # 示例:查询status=1的用户分页,每页10条,取第2页数据(假设数据量足够)
    status = 1
    per_page = 10
    page_no = 2

    # 使用Django的ORM
    from django.contrib.auth.models import User

    query = User.objects.filter(status=status).values("id", "username", "first_name")
    one_page_data_list, page_no, page_data = paginator(query, per_page, page_no)
    # one_page_data_list 即为第二页数据,例如:[{"id": 1, "username": "111", "first_name": "aaa"}]
    print one_page_data_list


def demo_raw():
    """使用原生sql实现相同分页"""
    # 示例:查询status=1的用户分页,每页10条,取第2页数据(假设数据量足够)
    status = 1
    per_page = 10
    page_no = 2

    sql = "select id, username, first_name from auth_user where status=%(status)s"
    params = {"status": status}  # 使用params防止sql注入
    query = QueryWrapper(sql, params, "default")
    one_page_data_list, page_no, page_data = paginator(query, per_page, page_no)
    # one_page_data_list 同ORM获取数据一样
    print one_page_data_list


if __name__ == "__main__":
    demo_orm()
    demo_raw()

© 著作权归作者所有

共有 人打赏支持
张豪飞
粉丝 26
博文 35
码字总数 18611
作品 0
郑州
程序员
Django Paginator属性及方法

Django分页的基本操作在Django文档有简单的例子,基本上看一下就知道。核心代码在django.core.paginator.py中。 分页对象Paginator: 只需提供两个必要的参数,第一个就是用于展示的数据(o...

北方攻城师 ⋅ 2015/06/17 ⋅ 0

django paginator基本使用方法

分页是Web应用常用的手法,Django提供了一个分页器类Paginator(django.core.paginator.Paginator),可以很容易的实现分页的功能。该类有两个构造参数,一个是数据的集合,另一个是每页放多少...

jacked ⋅ 2015/11/13 ⋅ 0

Django+boostrap分页(1)

源起 我想要优雅地使用+ 来实现分页,忽然发现不知道该如何做起我照葫芦画瓢知道了怎么使用列表组件,也大概知道怎么使用,但是放到一起我就彻底懵逼了。 资料收集 基本分页演示 如果想使用禁...

mhye ⋅ 2016/10/09 ⋅ 0

django分页器paginator使用简单说明

Django之分页功能 Django提供了一个新的类来帮助你管理分页数据,这个类存放在django/core/paginator.py.它可以接收列表、元组或其它可迭代的对象。 基本语法 class Paginator(object): def...

四京 ⋅ 2017/11/10 ⋅ 0

如何用Django分页器实现文章分页?

1、概述 Django有自带的分页器,可以将数据分在不同的页面中,并提供一些属性和方法实现对分页数据的操作。分页功能的类位于django/core/paginator.py中。 2、数据准备 在具体实现分类器功能...

mcyJacky的博客 ⋅ 2017/12/11 ⋅ 0

Django-----分页

一、目的 因为往往数据库中的数据在前端页面展示出来一页肯定是不够的,而一个网页的容量就那么大,所以肯定要分页显示。 二、实施 其实仔细想想,如果数据量小的话,直接在后台的views处理函...

AltBoy ⋅ 2017/06/26 ⋅ 0

Django中扩展Paginator实现分页

Django中已经实现了很多功能,基本上只要我们需要的功能,都能够找到相应的包。要在Django中实现分页显示,只需要简单地使用Paginator就可以实现了。 首先,需要在应用的views.py中添加如下引...

晴风晓月 ⋅ 2013/05/29 ⋅ 0

Django 基于类的视图源码分析 三

列表类通用视图(list.py) 此文件包含用于显示数据列表常用的类和工具类。不仅可以方便的用于显示基于模型(Model)的数据列表,也可以用于显示自定义数据列表。 ![list.py类图][1] 此图中绿色部...

XuYuan ⋅ 2013/02/22 ⋅ 0

Django 之 基于类的视图源码分析

基于类的视图(Class-based view)是Django 1.3引入的新的视图编写方式,用于取代以前基于函数(Function-based)方式。 借助于OO和Python中方便的多重继承特性,基于类的视图可以提供更好的抽象...

首席安全砖家 ⋅ 2013/06/11 ⋅ 0

django分页-Paginator类

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, ......

江北 ⋅ 2014/05/25 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

PHP语言系统ZBLOG或许无法重现月光博客的闪耀历史[图]

最近在写博客,希望通过自己努力打造一个优秀的教育类主题博客,名动江湖,但是问题来了,现在写博客还有前途吗?面对强大的自媒体站点围剿,还有信心和可能型吗? 至于程序部分,我选择了P...

原创小博客 ⋅ 15分钟前 ⋅ 0

IntelliJ IDEA 2018.1新特性

工欲善其事必先利其器,如果有一款IDE可以让你更高效地专注于开发以及源码阅读,为什么不试一试? 本文转载自:netty技术内幕 3月27日,jetbrains正式发布期待已久的IntelliJ IDEA 2018.1,再...

Romane ⋅ 40分钟前 ⋅ 0

浅谈设计模式之工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻...

佛系程序猿灬 ⋅ 今天 ⋅ 0

Dockerfile基础命令总结

FROM 指定使用的基础base image FROM scratch # 制作base image ,不使用任何基础imageFROM centos # 使用base imageFROM ubuntu:14.04 尽量使用官方的base image,为了安全 LABEL 描述作...

ExtreU ⋅ 昨天 ⋅ 0

存储,对比私有云和公有云的不同

导读 说起公共存储,很难不与后网络公司时代的选择性外包联系起来,但尽管如此,它还是具备着简单和固有的可用性。公共存储的名字听起来也缺乏专有性,很像是把东西直接堆放在那里而不会得到...

问题终结者 ⋅ 昨天 ⋅ 0

C++难点解析之const修饰符

C++难点解析之const修饰符 c++ 相比于其他编程语言,可能是最为难掌握,概念最为复杂的。结合自己平时的C++使用经验,这里将会列举出一些常见的难点并给出相应的解释。 const修饰符 const在c...

jackie8tao ⋅ 昨天 ⋅ 0

聊聊spring cloud netflix的HystrixCommands

序 本文主要研究一下spring cloud netflix的HystrixCommands。 maven <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-clo......

go4it ⋅ 昨天 ⋅ 0

Confluence 6 从其他备份中恢复数据

一般来说,Confluence 数据库可以从 Administration Console 或者 Confluence Setup Wizard 中进行恢复。 如果你在恢复压缩的 XML 备份的时候遇到了问题,你还是可以对整个站点进行恢复的,如...

honeymose ⋅ 昨天 ⋅ 0

myeclipse10 快速搭建spring boot开发环境(入门)

1.创建一个maven的web项目 注意上面标红的部分记得选上 2.创建的maven目录结构,有缺失的目录可以自己建立目录补充 补充后 这时候一个maven的web项目创建完成 3.配置pom.xml配置文件 <proje...

小海bug ⋅ 昨天 ⋅ 0

nginx.conf

=========================================================================== nginx.conf =========================================================================== user nobody; #......

A__17 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部