Django自带序列化组件;分页器

django自带的序列化组件

代码实现序列化

models.py

class User(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    gender_choice = (
        (1, 'male'),
        (2, 'female'),
        (3, 'others')
    )
    gender = models.IntegerField(choices=gender_choice)
    addr = models.CharField(max_length=32)

views.py

from app01 import models
from django.http import JsonResponse

def data(request):
    data_list = []  # [{}, {}, {}]
    user_queryset = models.User.objects.all()
    for user_obj in user_queryset:
        data_list.append({
            'pk':user_obj.pk,
            'name':user_obj.name,
            'age':user_obj.age,
            'gender':user_obj.gender,
            'gender_real':user_obj.get_gender_display(),
            'addr':user_obj.addr
        })
    return JsonResponse(data_list,safe=False)

前后端分离之后,django orm产生的queryset无法直接被前端识别,还是需要 json格式数据(硬通货)

bejson.com

可以将json格式数据优化或者美化

序列化组件

Django自带的序列化组件可以省略我们上述的操作

from app01 import models
from django.http import JsonResponse
from django.core import serializers

def d_data(request):
    user_queryset = models.User.objects.all()
    ret = serializers.serialize('json', user_queryset)
    return HttpResponse(ret)

批量数据操作

方式一

def many_data(request):
    for i in range(100000):
        models.Book.objects.create(title=f'第{i}本书')   book_queryset = models.Books.objects.all()    return render(request,'many_data.html',locals())

循环插入10万条数据, 频繁走数据库操作,效率极低,不推荐!!!

方式二

批量插入

def many_data(request):
    book_list = []
    for i in range(100000):     # 先用类产生一个对象
        source_book_obj = models.Books(title=f'第{i}本书')     # 将对象追加到列表中
        book_list.append(source_book_obj)
    models.Books.objects.bulk_create(book_list)  # 批量插入
    book_queryset = models.Books.objects.all()
   return render(request,'many_data.html',locals())

分页器

推导流程

针对上一小节批量插入的数据,我们在前端展示的时候发现一个很严重的问题,一页展示了所有的数据,数据量太大,查看不方便

针对数据量大但又需要全部展示给用户观看的情况下,我们统一做法都是做分页处理

分页推导

首先我们需要明确的时候,get请求也是可以携带参数的,所以我们在朝后端发送查看数据的同时可以携带一个参数告诉后端我们想看第几页的数据

其次我们还需要知道一个点,queryset对象是支持索引取值和切片操作的,但是不支持负数索引情况

接下来我们就可以推导我们的自定义分页器步骤了

current_page = request.GET.get("page",1)  # 获取用户想访问的页码  如果没有 默认展示第一页
try:  # 由于后端接受到的前端数据是字符串类型所以我们这里做类型转换处理加异常捕获
  current_page = int(current_page)
except Exception as e:
  current_page = 1
还需要定义页面到底展示几条数据
per_page_num = 10  # 一页展示10条数据

需要对总数据进行切片操作 需要确定切片起始位置和终止位置
start_page = ?
end_page = ?
"""
下面需要研究current_page、per_page_num、start_page、end_page四个参数之间的数据关系
per_page_num = 10
current_page                start_page                  end_page
    1                           0                           10
    2                           10                          20
    3                           20                          30
    4                           30                          40

per_page_num = 5
current_page                start_page                  end_page
    1                           0                           5
    2                           5                           10
    3                           10                          15
    4                           15                          20
可以很明显的看出规律
start_page = (current_page - 1) * per_page_num
end_page =  current_page* per_page_num
"""

Django自带序列化组件;分页器

数据总页面获取

如果总数据有100条,每页展示10条,总共需要10页

如果总数据有101条,每页展示10条,总共需要11页

这里需要用到一个内置方法divmod

内置方法divmod

>>> divmod(100,10)
(10, 0)  # 10页
>>> divmod(101,10)
(10, 1)  # 11页
>>> divmod(99,10)
(9, 9)  # 10页

余数只要不是0就需要在第一个数字上加一

我们可以判断元祖的第二个数字是否为0从而确定到底需要多少页来展示数据

book_queryset = models.Book.objects.all()
all_count = book_queryset.count()  # 数据总条数
all_pager, more = divmod(all_count, per_page_num)
if more:  # 有余数则总页数加一
  all_pager += 1

利用start_page和end_page对总数据进行切片取值再传入前端页面

book_list = models.Book.objects.all()[start_page:end_page]
return render(request,'booklist.html',locals())

前端页面代码编写

{% for book in book_list %}
    <p>{{ book.title }}p>
{% endfor %}

总结推导流程

  1. all()结果集支持正数的索引切片
  2. 分页相关参数数学关系
  3. 后端渲染前端分页代码
  4. 后端限制分页展示数量
  5. 当页面小于6或者大于N都需要额外限制

自定义分页器

以后可能很多地方都需要使用分页,不可能重复编写,所以封装成了模块

封装的模块可以另外创建文件夹utils里面的mypage来存储分页器模块

mypage.py

Django自带序列化组件;分页器
def init(self, current_page, all_count, per_page_num=2, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
"""
try:
current_page
= int(current_page)
except Exception as e:
current_page
= 1
    <span>if</span> current_page &lt; 1<span>:
        current_page </span>= 1<span>

    self.current_page </span>=<span> current_page

    self.all_count </span>=<span> all_count
    self.per_page_num </span>=<span> per_page_num

    </span><span>#</span><span> &#x603B;&#x9875;&#x7801;</span>
    all_pager, tmp =<span> divmod(all_count, per_page_num)
    </span><span>if</span><span> tmp:
        all_pager </span>+= 1<span>
    self.all_pager </span>=<span> all_pager

    self.pager_count </span>=<span> pager_count
    self.pager_count_half </span>= int((pager_count - 1) / 2<span>)

@property
</span><span>def</span><span> start(self):
    </span><span>return</span> (self.current_page - 1) *<span> self.per_page_num

@property
</span><span>def</span><span> end(self):
    </span><span>return</span> self.current_page *<span> self.per_page_num

</span><span>def</span><span> page_html(self):
    </span><span>#</span><span> &#x5982;&#x679C;&#x603B;&#x9875;&#x7801; &lt; 11&#x4E2A;&#xFF1A;</span>
    <span>if</span> self.all_pager <=<span> self.pager_count:
        pager_start = 1<span>
        pager_end </span>= self.all_pager + 1
    <span>#</span><span> &#x603B;&#x9875;&#x7801;  &gt; 11</span>
    <span>else</span><span>:
        </span><span>#</span><span> &#x5F53;&#x524D;&#x9875;&#x5982;&#x679C;<=页面上最多显示11>
        <span>if</span> self.current_page <=<span> self.pager_count_half:
            pager_start <!--=<span--><!--=页面上最多显示11--></span>= 1<span>
            pager_end </span>= self.pager_count + 1

        <span>#</span><span> &#x5F53;&#x524D;&#x9875;&#x5927;&#x4E8E;5</span>
        <span>else</span><span>:
            </span><span>#</span><span> &#x9875;&#x7801;&#x7FFB;&#x5230;&#x6700;&#x540E;</span>
            <span>if</span> (self.current_page + self.pager_count_half) &gt;<span> self.all_pager:
                pager_end </span>= self.all_pager + 1<span>
                pager_start </span>= self.all_pager - self.pager_count + 1
            <span>else</span><span>:
                pager_start </span>= self.current_page -<span> self.pager_count_half
                pager_end </span>= self.current_page + self.pager_count_half + 1<span>

    page_html_list </span>=<span> []
    </span><span>#</span><span> &#x6DFB;&#x52A0;&#x524D;&#x9762;&#x7684;nav&#x548C;ul&#x6807;&#x7B7E;</span>
    page_html_list.append(<span>&apos;&apos;&apos;</span><span>&apos;&apos;&apos;</span><span>)
    first_page </span>= <span>&apos;</span><span><li><a>&#x9996;&#x9875;</a></li></span><span>&apos;</span> % (1<span>)
    page_html_list.append(first_page)

    </span><span>if</span> self.current_page <=>:
        prev_page = <span>&apos;</span><span><li><a>&#x4E0A;&#x4E00;&#x9875;</a></li></span><span>&apos;</span>
    <span>else</span><span>:
        prev_page </span>= <span>&apos;</span><span><li><a>&#x4E0A;&#x4E00;&#x9875;</a></li></span><span>&apos;</span> % (self.current_page - 1<span>,)

    page_html_list.append(prev_page)

    </span><span>for</span> i <span>in</span><span> range(pager_start, pager_end):
        </span><span>if</span> i ==<span> self.current_page:
            temp </span>= <span>&apos;</span><span><li><a>%s</a></li></span><span>&apos;</span> %<span> (i, i,)
        </span><span>else</span><span>:
            temp </span>= <span>&apos;</span><span><li><a>%s</a></li></span><span>&apos;</span> %<span> (i, i,)
        page_html_list.append(temp)

    </span><span>if</span> self.current_page &gt;=<span> self.all_pager:
        next_page </span>= <span>&apos;</span><span><li><a>&#x4E0B;&#x4E00;&#x9875;</a></li></span><span>&apos;</span>
    <span>else</span><span>:
        next_page </span>= <span>&apos;</span><span><li><a>&#x4E0B;&#x4E00;&#x9875;</a></li></span><span>&apos;</span> % (self.current_page + 1<span>,)
    page_html_list.append(next_page)

    last_page </span>= <span>&apos;</span><span><li><a>&#x5C3E;&#x9875;</a></li></span><span>&apos;</span> %<span> (self.all_pager,)
    page_html_list.append(last_page)
    </span><span>#</span><span> &#x5C3E;&#x90E8;&#x6DFB;&#x52A0;&#x6807;&#x7B7E;</span>
    page_html_list.append(<span>&apos;&apos;&apos;</span><span>&apos;&apos;&apos;</span><span>)
    </span><span>return</span> <span>&apos;&apos;</span>.join(page_html_list)<!--=--><!--=<span--></pre>View Code

后端

from utils import mypage
book_queryset = models.Books.objects.all()
产生分页器对象
page_obj = mypage.Pagination(current_page=request.GET.get('page'),all_count=book_queryset.count())
产生分页数据对象
page_queryset = book_queryset[page_obj.start:page_obj.end]
return render(request,'many_data.html',locals())

前端

<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for book in page_queryset %}
            <p>{{ book.title }}p>
            {% endfor %}
            {{ page_obj.page_html|safe }}
        div>
    div>
div>

Django自带序列化组件;分页器

Original: https://www.cnblogs.com/zzs0626/p/16294016.html
Author: 顺溜_7
Title: Django自带序列化组件;分页器

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/582434/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • redis持久化存储

    redis持久化存储 redis多被用于缓存和消息中间件,当被用作缓存时,数据的读写都是在内存中进行的,而内存一旦在主机断电或者主机重启时里面的数据将被清空,为保证数据不被丢失,r…

    Linux 2023年6月7日
    0105
  • 配置phpstorm支持less自动编译css

    安装node.js 安装less npm install less -g 安装css压缩插件less-plugin-clean-css(此步骤非必选) npm install le…

    Linux 2023年6月13日
    090
  • Git的使用

    Git的概念 Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的项目 Git的安装 Git官网https://git-scm.com/下载安装直接下一步…

    Linux 2023年6月13日
    084
  • [云原生]Kubernetes-实战入门(第4章)

    一、Namespace 二、Pod 三、Label 四、Deployment 五、Service 参考: Kubernetes(K8S) 入门进阶实战完整教程,黑马程序员K8S全套…

    Linux 2023年6月13日
    0114
  • BKT的胡测题解:第一套第二题reactor

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/Grharris/p/11530297.htmlAuth…

    Linux 2023年6月6日
    094
  • qsort的cmp函数理解

    近期频繁使用qsort函数,但是对于cmp函数却一直不太熟悉,现用现查。故写一篇小笔记记录一下。 函数原型: void qsort(void *base,size_t NumEle…

    Linux 2023年6月8日
    069
  • 【原创】Linux虚拟化KVM-Qemu分析(七)之timer虚拟化

    背景 Read the fucking source code! –By 鲁迅 A picture is worth a thousand words. –…

    Linux 2023年6月8日
    0104
  • POJ3368(Frequent values)–线段树

    题目在这里3368Accepted 7312K 1829MSC++ 6936B 题意为给你一组数据,再给定一组区间,问你这个区间内出现次数最多的元素的次数是多少。 我还记得这题是学…

    Linux 2023年6月7日
    0108
  • Linux下如何修复陈旧的第三方微信版本electronic-wechat

    因为现在的Linux发行版软件库太新的缘故,导致陈旧的electronic-wechat的文本引擎库不能正确运行,一般表现为harfbuzz too old等错误。 即使你把har…

    Linux 2023年6月14日
    0108
  • MySQL注入 利用系统读、写文件

    MySQL能读写系统文件的前提 不同系统、不同的数据库版本有细微差异,以下实验在Windows10和Mysql 5.7.26下操作; 1.拥有该File的读权限 、 该目录写的权限…

    Linux 2023年6月6日
    0108
  • 搭建Nginx(haproxy)+keepalived+Tomcat双主高可用负载均衡

    周末的时候一个正在学Linux的朋友问我,高可用怎么玩?我和他微信了将近三个小时,把Nginx和haproxy双主高可用教给他了,今天突然想把这个给写进博客里,供给那些正在学习Li…

    Linux 2023年6月8日
    066
  • WEB自动化-04-Cypress 测试用例编写和组织

    4 测试用例编写和组织 4.1 用例结构 Cypress是建立在 Mocha和 Chai之上,因此同时支持Chai的 BDD和 TDD两种风格。如果你熟悉JavaScript风格的…

    Linux 2023年6月7日
    0111
  • Quartus II 13.0 sp1的官方下载页面

    今天为了下个ModelSim跑到网上去找下载资源,清一色的百度网盘,下载速度60k/s,简直有病,于是跑到Intel官网上把连接挖出来了,供各位直接下载 实测使用IDM多线程下载速…

    Linux 2023年6月13日
    0170
  • SSH 完全教程 2

    SSH 默认采用密码登录,这种方法有很多缺点,简单的密码不安全,复杂的密码不容易记忆,每次手动输入也很麻烦。密钥登录是b比密码登录更好的解决方案。 密钥是什么 密钥(key)是一个…

    Linux 2023年6月7日
    068
  • 音视频技术入门课- 05 使用FFmpeg与OBS进行直播推流

    做直播推流的前提是要有直播服务器接收直播流,所以需要我们自己建设一个流媒体服务器。 流媒体服务器SRS SRS是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/H…

    Linux 2023年6月7日
    0106
  • rsync

    Rsync-远程同步 简介 rsync是linux系统下的数据镜像备份工具。使用快速增量备份工具Remote Sync可以远程同步,支持本地复制,或者与其他SSH、rsync主机同…

    Linux 2023年6月13日
    066
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球