知识预览

分页

Django的分页器(paginator)

view

  1. from django.shortcuts import render,HttpResponse
  2.  
  3. # Create your views here.
  4. from app01.models import *
  5. from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
  6.  
  7. def index(request):
  8.  
  9. '''
  10. 批量导入数据:
  11.  
  12. Booklist=[]
  13. for i in range(100):
  14. Booklist.append(Book(title="book"+str(i),price=30+i*i))
  15. Book.objects.bulk_create(Booklist)
  16. '''
  17.  
  18. '''
  19. 分页器的使用:
  20.  
  21. book_list=Book.objects.all()
  22.  
  23. paginator = Paginator(book_list, 10)
  24.  
  25. print("count:",paginator.count) #数据总数
  26. print("num_pages",paginator.num_pages) #总页数
  27. print("page_range",paginator.page_range) #页码的列表
  28.  
  29. page1=paginator.page(1) #第1页的page对象
  30. for i in page1: #遍历第1页的所有数据对象
  31. print(i)
  32.  
  33. print(page1.object_list) #第1页的所有数据
  34.  
  35. page2=paginator.page(2)
  36.  
  37. print(page2.has_next()) #是否有下一页
  38. print(page2.next_page_number()) #下一页的页码
  39. print(page2.has_previous()) #是否有上一页
  40. print(page2.previous_page_number()) #上一页的页码
  41.  
  42. # 抛错
  43. #page=paginator.page(12) # error:EmptyPage
  44.  
  45. #page=paginator.page("z") # error:PageNotAnInteger
  46.  
  47. '''
  48.  
  49. book_list=Book.objects.all()
  50.  
  51. paginator = Paginator(book_list, 10)
  52. page = request.GET.get('page',1)
  53. currentPage=int(page)
  54.  
  55. try:
  56. print(page)
  57. book_list = paginator.page(page)
  58. except PageNotAnInteger:
  59. book_list = paginator.page(1)
  60. except EmptyPage:
  61. book_list = paginator.page(paginator.num_pages)
  62.  
  63. return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})

index.html:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  7. </head>
  8. <body>
  9.  
  10. <div class="container">
  11.  
  12. <h4>分页器</h4>
  13. <ul>
  14.  
  15. {% for book in book_list %}
  16. <li>{{ book.title }} -----{{ book.price }}</li>
  17. {% endfor %}
  18.  
  19. </ul>
  20.  
  21. <ul class="pagination" id="pager">
  22.  
  23. {% if book_list.has_previous %}
  24. <li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>
  25. {% else %}
  26. <li class="previous disabled"><a href="#">上一页</a></li>
  27. {% endif %}
  28.  
  29. {% for num in paginator.page_range %}
  30.  
  31. {% if num == currentPage %}
  32. <li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>
  33. {% else %}
  34. <li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>
  35.  
  36. {% endif %}
  37. {% endfor %}
  38.  
  39. {% if book_list.has_next %}
  40. <li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>
  41. {% else %}
  42. <li class="next disabled"><a href="#">下一页</a></li>
  43. {% endif %}
  44.  
  45. </ul>
  46. </div>
  47.  
  48. </body>
  49. </html>

扩展

  1. def index(request):
  2.  
  3. book_list=Book.objects.all()
  4.  
  5. paginator = Paginator(book_list, 15)
  6. page = request.GET.get('page',1)
  7. currentPage=int(page)
  8.  
  9. # 如果页数十分多时,换另外一种显示方式
  10. if paginator.num_pages>30:
  11.  
  12. if currentPage-5<1:
  13. pageRange=range(1,11)
  14. elif currentPage+5>paginator.num_pages:
  15. pageRange=range(currentPage-5,paginator.num_pages+1)
  16.  
  17. else:
  18. pageRange=range(currentPage-5,currentPage+5)
  19.  
  20. else:
  21. pageRange=paginator.page_range
  22.  
  23. try:
  24. print(page)
  25. book_list = paginator.page(page)
  26. except PageNotAnInteger:
  27. book_list = paginator.page(1)
  28. except EmptyPage:
  29. book_list = paginator.page(paginator.num_pages)
  30.  
  31. return render(request,"index.html",locals())

自定义分页器

  1. """
  2. 分页组件使用示例:
  3.  
  4. obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info)
  5. page_user_list = USER_LIST[obj.start:obj.end]
  6. page_html = obj.page_html()
  7.  
  8. return render(request,'index.html',{'users':page_user_list,'page_html':page_html})
  9.  
  10. """
  11.  
  12. class Pagination(object):
  13.  
  14. def __init__(self,current_page,all_count,base_url,per_page_num=2,pager_count=11):
  15. """
  16. 封装分页相关数据
  17. :param current_page: 当前页
  18. :param all_count: 数据库中的数据总条数
  19. :param per_page_num: 每页显示的数据条数
  20. :param base_url: 分页中显示的URL前缀
  21. :param pager_count: 最多显示的页码个数
  22. """
  23.  
  24. try:
  25. current_page = int(current_page)
  26. except Exception as e:
  27. current_page = 1
  28.  
  29. if current_page <1:
  30. current_page = 1
  31.  
  32. self.current_page = current_page
  33.  
  34. self.all_count = all_count
  35. self.per_page_num = per_page_num
  36.  
  37. self.base_url = base_url
  38.  
  39. # 总页码
  40. all_pager, tmp = divmod(all_count, per_page_num)
  41. if tmp:
  42. all_pager += 1
  43. self.all_pager = all_pager
  44.  
  45. self.pager_count = pager_count
  46. self.pager_count_half = int((pager_count - 1) / 2)
  47.  
  48. @property
  49. def start(self):
  50. return (self.current_page - 1) * self.per_page_num
  51.  
  52. @property
  53. def end(self):
  54. return self.current_page * self.per_page_num
  55.  
  56. def page_html(self):
  57. # 如果总页码 < 11个:
  58. if self.all_pager <= self.pager_count:
  59. pager_start = 1
  60. pager_end = self.all_pager + 1
  61. # 总页码 > 11
  62. else:
  63. # 当前页如果<=页面上最多显示11/2个页码
  64. if self.current_page <= self.pager_count_half:
  65. pager_start = 1
  66. pager_end = self.pager_count + 1
  67.  
  68. # 当前页大于5
  69. else:
  70. # 页码翻到最后
  71. if (self.current_page + self.pager_count_half) > self.all_pager:
  72. pager_end = self.all_pager + 1
  73. pager_start = self.all_pager - self.pager_count + 1
  74. else:
  75. pager_start = self.current_page - self.pager_count_half
  76. pager_end = self.current_page + self.pager_count_half + 1
  77.  
  78. page_html_list = []
  79.  
  80. first_page = '<li><a href="%s?page=%s">首页</a></li>' % (self.base_url,1,)
  81. page_html_list.append(first_page)
  82.  
  83. if self.current_page <= 1:
  84. prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
  85. else:
  86. prev_page = '<li><a href="%s?page=%s">上一页</a></li>' % (self.base_url,self.current_page - 1,)
  87.  
  88. page_html_list.append(prev_page)
  89.  
  90. for i in range(pager_start, pager_end):
  91. if i == self.current_page:
  92. temp = '<li class="active"><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)
  93. else:
  94. temp = '<li><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)
  95. page_html_list.append(temp)
  96.  
  97. if self.current_page >= self.all_pager:
  98. next_page = '<li class="disabled"><a href="#">下一页</a></li>'
  99. else:
  100. next_page = '<li><a href="%s?page=%s">下一页</a></li>' % (self.base_url,self.current_page + 1,)
  101. page_html_list.append(next_page)
  102.  
  103. last_page = '<li><a href="%s?page=%s">尾页</a></li>' % (self.base_url,self.all_pager,)
  104. page_html_list.append(last_page)
  105.  
  106. return ''.join(page_html_list)

中间件

中间件的概念

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

Django的中间件的定义:

1
Middleware is a framework of hooks into Django’s request/response processing. <br>It’s a light, low-level “plugin” system for globally altering Django’s input or output.

如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。

可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。

大家可能频繁在view使用request.user吧。 Django想在每个view执行之前把user设置为request的属性,于是就用了一个中间件来实现这个目标。所以Django提供了可以修改request 对象的中间件 AuthenticationMiddleware

Django默认的Middleware

  1. MIDDLEWARE = [
  2. 'django.middleware.security.SecurityMiddleware',
  3. 'django.contrib.sessions.middleware.SessionMiddleware',
  4. 'django.middleware.common.CommonMiddleware',
  5. 'django.middleware.csrf.CsrfViewMiddleware',
  6. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  7. 'django.contrib.messages.middleware.MessageMiddleware',
  8. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  9. ]

每一个中间件都有具体的功能。

自定义中间件

中间件中一共有四个方法:

  1. process_request
  2.  
  3. process_view
  4.  
  5. process_exception
  6.  
  7. process_response

process_request,process_response

当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。

上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin

需要导入

1
from django.utils.deprecation import MiddlewareMixin

in views:

  1. def index(request):
  2.  
  3. print("view函数...")
  4. return HttpResponse("OK")

in Mymiddlewares.py:

  1. from django.utils.deprecation import MiddlewareMixin
  2. from django.shortcuts import HttpResponse
  3.  
  4. class Md1(MiddlewareMixin):
  5.  
  6. def process_request(self,request):
  7. print("Md1请求")
  8.  
  9. def process_response(self,request,response):
  10. print("Md1返回")
  11. return response
  12.  
  13. class Md2(MiddlewareMixin):
  14.  
  15. def process_request(self,request):
  16. print("Md2请求")
    #return HttpResponse("Md2中断")
  17. def process_response(self,request,response):
  18. print("Md2返回")
  19. return response

结果:

  1. Md1请求
  2. Md2请求
  3. view函数...
  4. Md2返回
  5. Md1返回

注意:如果当请求到达请求2的时候直接不符合条件返回,即return HttpResponse("Md2中断"),程序将把请求直接发给中间件2返回,然后依次返回到请求者,结果如下:

返回Md2中断的页面,后台打印如下:

  1. Md1请求
  2. Md2请求
  3. Md2返回
  4. Md1返回

流程图如下:

process_view

1
process_view(self, request, callback, callback_args, callback_kwargs)

Mymiddlewares.py修改如下

  1. from django.utils.deprecation import MiddlewareMixin
  2. from django.shortcuts import HttpResponse
  3.  
  4. class Md1(MiddlewareMixin):
  5.  
  6. def process_request(self,request):
  7. print("Md1请求")
  8. #return HttpResponse("Md1中断")
  9. def process_response(self,request,response):
  10. print("Md1返回")
  11. return response
  12.  
  13. def process_view(self, request, callback, callback_args, callback_kwargs):
  14. print("Md1view")
  15.  
  16. class Md2(MiddlewareMixin):
  17.  
  18. def process_request(self,request):
  19. print("Md2请求")
  20. return HttpResponse("Md2中断")
  21. def process_response(self,request,response):
  22. print("Md2返回")
  23. return response
  24.  
  25. def process_view(self, request, callback, callback_args, callback_kwargs):
  26. print("Md2view")

结果如下:

  1. Md1请求
  2. Md2请求
  3. Md1view
  4. Md2view
  5. view函数...
  6. Md2返回
  7. Md1返回

下图进行分析上面的过程:

当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户。

process_view可以用来调用视图函数:

  1. class Md1(MiddlewareMixin):
  2.  
  3. def process_request(self,request):
  4. print("Md1请求")
  5. #return HttpResponse("Md1中断")
  6. def process_response(self,request,response):
  7. print("Md1返回")
  8. return response
  9.  
  10. def process_view(self, request, callback, callback_args, callback_kwargs):
  11.  
  12. # return HttpResponse("hello")
  13.  
  14. response=callback(request,*callback_args,**callback_kwargs)
  15. return response

结果如下:

  1. Md1请求
  2. Md2请求
  3. view函数...
  4. Md2返回
  5. Md1返回

注意:process_view如果有返回值,会越过其他的process_view以及视图函数,但是所有的process_response都还会执行。

process_exception

1
process_exception(self, request, exception)

示例修改如下:

  1. class Md1(MiddlewareMixin):
  2.  
  3. def process_request(self,request):
  4. print("Md1请求")
  5. #return HttpResponse("Md1中断")
  6. def process_response(self,request,response):
  7. print("Md1返回")
  8. return response
  9.  
  10. def process_view(self, request, callback, callback_args, callback_kwargs):
  11.  
  12. # return HttpResponse("hello")
  13.  
  14. # response=callback(request,*callback_args,**callback_kwargs)
  15. # return response
  16. print("md1 process_view...")
  17.  
  18. def process_exception(self):
  19. print("md1 process_exception...")
  20.  
  21. class Md2(MiddlewareMixin):
  22.  
  23. def process_request(self,request):
  24. print("Md2请求")
  25. # return HttpResponse("Md2中断")
  26. def process_response(self,request,response):
  27. print("Md2返回")
  28. return response
  29. def process_view(self, request, callback, callback_args, callback_kwargs):
  30. print("md2 process_view...")
  31.  
  32. def process_exception(self):
  33. print("md1 process_exception...")

结果如下:

  1. Md1请求
  2. Md2请求
  3. md1 process_view...
  4. md2 process_view...
  5. view函数...
  6.  
  7. Md2返回
  8. Md1返回

流程图如下:

当views出现错误时:

将md2的process_exception修改如下:

  1. def process_exception(self,request,exception):
  2.  
  3. print("md2 process_exception...")
  4. return HttpResponse("error")

结果如下:

  1. Md1请求
  2. Md2请求
  3. md1 process_view...
  4. md2 process_view...
  5. view函数...
  6. md2 process_exception...
  7. Md2返回
  8. Md1返回

Django-进阶 分页,中间件的更多相关文章

  1. Django进阶之中间件

    中间件简介 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在djang ...

  2. Django 进阶(分页器&中间件)

    分页 Django的分页器(paginator) view from django.shortcuts import render,HttpResponse # Create your views h ...

  3. Python Django的分页,Form验证,中间件

    本节内容 Django的分页 Form 中间件 1 Django 分页 1.1 Django自带的分页 1.首先来看下我的测试数据环境 ############ models.py ######### ...

  4. Django进阶(路由系统、中间件、缓存、Cookie和Session、Ajax发送数据

    路由系统 1.每个路由规则对应一个view中的函数 url(r'^index/(\d*)', views.index), url(r'^manage/(?P<name>\w*)/(?P&l ...

  5. Django【进阶】中间件

    中间件   一.概念 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 其 ...

  6. Python之路,Day16 - Django 进阶

    Python之路,Day16 - Django 进阶   本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproj ...

  7. python web框架 Django进阶

    django 进阶 基础中,一些操作都是手动创建连接的非主流操作,这样显得太low,当然也是为了熟悉这个框架! 实际中,django自带连接数据库和创建app的机制,同时还有更完善的路由系统机制.既然 ...

  8. Django进阶2

    一.ORM操作进阶 ForeignKey关联 示例models from django.db import models # Create your models here. class User(m ...

  9. Django进阶篇【1】

    注:本篇是Django进阶篇章,适合人群:有Django基础,关于Django基础篇,将在下一章节中补充! 首先我们一起了解下Django整个请求生命周期: Django 请求流程,生命周期: 路由部 ...

  10. Django进阶知识

    drf学习之Django进阶点 一.Django migrations原理 1.makemigrattions: 相当于在每个app下的migrations文件夹下生成一个py脚本文件用于创建表或则修 ...

随机推荐

  1. lua调试小技巧

    lua中,如果碰到某个属性值改变了,但是修改的地方又特别多,调试就特别麻烦了,有个小技巧,直接贴代码 local m = {    __index = function( t, k )         ...

  2. webdriver与JS操作浏览器元素

    1.JQuery的选择器实例 语法 描述 $(this) 当前 HTML 元素 $("p") 所有 <p> 元素 $("p.intro") 所有 c ...

  3. 正则表达式备忘(基于JavaScript)

    基于JS学习的正则表达式 备忘 e.g.匹配以0开头的三位或四位区号,以-分格的7或8位电话号码var reg1 = /^0\d{2,3}\-\d{7,8}$/;或var reg1 = new Reg ...

  4. 转 Hadoop傻瓜化:Datameer大数据收入翻三番

      淘薛奎发布到 <数据极客> 06-28 16:04 随着分析正在成为企业IT的核心,昔日的BI- ETL-EDW分析范型已经完全落伍,不再适用.而力推“大数据傻瓜化”的Datameer ...

  5. 每天一个Linux命令(34)grep命令

          grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具 ...

  6. unigui中TUniDBEdit的OnEndDrag问题

    非常奇怪,unigui中TUniDBEdit未发布OnEndDrag属性,包括其子类:TUniDBNumberEdit.TUniDBFormattedNumberEdit.而其他数据感知组件都有OnE ...

  7. intel dpdk api interrupt module 中断模块介绍

    声明:此文档只做学习交流使用,请勿用作其他商业用途 author:朝阳_tonyE-mail : linzhaolover@gmail.comCreate Date: 2013-7-12 11:46: ...

  8. HTML5坦克大战1

    在JavaScript中,不要在变量为定义之前去使用,这样很难察觉并且无法运行. 颜色不对. 当我的坦克移动时,敌人坦克消失. tankGame3.html <!DOCTYPE html> ...

  9. js 格式华货币

    /*货币格式化*/ function formatMoney(num) { num = num.toString().replace(/\$|\,/g,''); if(isNaN(num)) { nu ...

  10. Java集合类--->入门上篇

    最近我又在研究Java语言,这是第五次还是第六次学习Java的集合类,你也许会惊讶为什么这么多次?哈哈,因为之前的我没有记录下来,忘记了,当然最主要还是觉得自己毅力不够,没有坚持.那么,这次我将换一种 ...