Django-分页、中间件和请求的声明周期
一、分页
相关连接:https://www.cnblogs.com/kongzhagen/p/6640975.html
一、Django的分页器(paginator)
1、view.py 视图
from django.shortcuts import render,HttpResponse# Create your views here. from app01.models import * from django.core.paginator import Paginator, EmptyPage, PageNotAnIntegerdef index(request):'''批量导入数据:Booklist=[]for i in range(100):Booklist.append(Book(title="book"+str(i),price=30+i*i))Book.objects.bulk_create(Booklist)'''''' 分页器的使用:book_list=Book.objects.all()paginator = Paginator(book_list, 10)print("count:",paginator.count) #数据总数print("num_pages",paginator.num_pages) #总页数print("page_range",paginator.page_range) #页码的列表page1=paginator.page(1) #第1页的page对象for i in page1: #遍历第1页的所有数据对象print(i)print(page1.object_list) #第1页的所有数据page2=paginator.page(2)print(page2.has_next()) #是否有下一页print(page2.next_page_number()) #下一页的页码print(page2.has_previous()) #是否有上一页print(page2.previous_page_number()) #上一页的页码# 抛错#page=paginator.page(12) # error:EmptyPage#page=paginator.page("z") # error:PageNotAnInteger'''book_list=Book.objects.all()paginator = Paginator(book_list, 10)page = request.GET.get('page',1)currentPage=int(page)try:print(page)book_list = paginator.page(page)except PageNotAnInteger:book_list = paginator.page(1)except EmptyPage:book_list = paginator.page(paginator.num_pages)return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})
2、index.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body><div class="container"><h4>分页器</h4><ul>{% for book in book_list %}<li>{{ book.title }} -----{{ book.price }}</li>{% endfor %}</ul><ul class="pagination" id="pager">{% if book_list.has_previous %}<li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>{% else %}<li class="previous disabled"><a href="#">上一页</a></li>{% endif %}{% for num in paginator.page_range %}{% if num == currentPage %}<li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>{% else %}<li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>{% endif %}{% endfor %}{% if book_list.has_next %}<li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>{% else %}<li class="next disabled"><a href="#">下一页</a></li>{% endif %}</ul> </div></body> </html>
3、扩展
def index(request):book_list=Book.objects.all()paginator = Paginator(book_list, 15)page = request.GET.get('page',1)currentPage=int(page)# 如果页数十分多时,换另外一种显示方式if paginator.num_pages>30:if currentPage-5<1:pageRange=range(1,11)elif currentPage+5>paginator.num_pages:pageRange=range(currentPage-5,paginator.num_pages+1)else:pageRange=range(currentPage-5,currentPage+5)else:pageRange=paginator.page_rangetry:print(page)book_list = paginator.page(page)except PageNotAnInteger:book_list = paginator.page(1)except EmptyPage:book_list = paginator.page(paginator.num_pages)return render(request,"index.html",locals())
二、自定义分页器
""" 分页组件使用示例:obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info)page_user_list = USER_LIST[obj.start:obj.end]page_html = obj.page_html()return render(request,'index.html',{'users':page_user_list,'page_html':page_html})"""class Pagination(object):def __init__(self,current_page,all_count,base_url,per_page_num=2,pager_count=11):"""封装分页相关数据:param current_page: 当前页:param all_count: 数据库中的数据总条数:param per_page_num: 每页显示的数据条数:param base_url: 分页中显示的URL前缀:param pager_count: 最多显示的页码个数"""try:current_page = int(current_page)except Exception as e:current_page = 1if current_page <1:current_page = 1self.current_page = current_pageself.all_count = all_countself.per_page_num = per_page_numself.base_url = base_url# 总页码all_pager, tmp = divmod(all_count, per_page_num)if tmp:all_pager += 1self.all_pager = all_pagerself.pager_count = pager_countself.pager_count_half = int((pager_count - 1) / 2)@propertydef start(self):return (self.current_page - 1) * self.per_page_num@propertydef end(self):return self.current_page * self.per_page_numdef page_html(self):# 如果总页码 < 11个:if self.all_pager <= self.pager_count:pager_start = 1pager_end = self.all_pager + 1# 总页码 > 11else:# 当前页如果<=页面上最多显示11/2个页码if self.current_page <= self.pager_count_half:pager_start = 1pager_end = self.pager_count + 1# 当前页大于5else:# 页码翻到最后if (self.current_page + self.pager_count_half) > self.all_pager:pager_end = self.all_pager + 1pager_start = self.all_pager - self.pager_count + 1else:pager_start = self.current_page - self.pager_count_halfpager_end = self.current_page + self.pager_count_half + 1page_html_list = []first_page = '<li><a href="%s?page=%s">首页</a></li>' % (self.base_url,1,)page_html_list.append(first_page)if self.current_page <= 1:prev_page = '<li class="disabled"><a href="#">上一页</a></li>'else:prev_page = '<li><a href="%s?page=%s">上一页</a></li>' % (self.base_url,self.current_page - 1,)page_html_list.append(prev_page)for i in range(pager_start, pager_end):if i == self.current_page:temp = '<li class="active"><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)else:temp = '<li><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)page_html_list.append(temp)if self.current_page >= self.all_pager:next_page = '<li class="disabled"><a href="#">下一页</a></li>'else:next_page = '<li><a href="%s?page=%s">下一页</a></li>' % (self.base_url,self.current_page + 1,)page_html_list.append(next_page)last_page = '<li><a href="%s?page=%s">尾页</a></li>' % (self.base_url,self.all_pager,)page_html_list.append(last_page)return ''.join(page_html_list)
二、中间件
一、中间件的概念
Django中叫中间件,其他框架种有的叫管道。
1、中间件的定义
中间件,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变Django的输入与输出。因为改变的是全局,所以需要谨慎使用,用不好会影响性能。
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
2、Django中间件的定义
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.
中间件是Django请求/响应处理的钩子框架。是一种轻的、低层次的“插件”系统,用于全局修改Django的输入或输出。
若你想修改请求,例如被传送到view中的HttpRequest对象;或者你想修改view返回的HttpResponse对象;你还想再view执行之前做一些操作,这些都可以使用middleware中间件来实现。
二、Django默认中间件使用
1、Django中间件 settings.py文件
Django想在每个view中执行之前把user设置为request的属性,于是就使用一个中间件来实现这个目标。这个修改request对象的中间件是AuthenticationMiddleware。
Django中默认的Middleware:
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware', ]
每一个中间是都有具体的功能。
2、中间的执行流程
Django中间件:https://www.cnblogs.com/huchong/p/7819296.html
中间件执行流程描述:
- 执行完所有的request方法 到达视图函数。
- 执行中间件的其他方法
- 经过所有response方法 返回客户端。
3、Django内置中间说明
https://my.oschina.net/liuyuantao/blog/756778
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware', #安全中间件'django.contrib.sessions.middleware.SessionMiddleware', #会话中间件,放在UpdateCacheMiddleware之后:会修改 大量协议头。'django.middleware.common.CommonMiddleware', #放在任何可能修改相应的中间件之前(因为它会生成ETags)。'django.middleware.csrf.CsrfViewMiddleware', #CSRF保护中间件,放在任何假设CSRF攻击被处理的视图中间件之前。'django.contrib.auth.middleware.AuthenticationMiddleware', #认证中间件,放在SessionMiddleware之后:因为它使用会话存储。'django.contrib.messages.middleware.MessageMiddleware', #消息中间件,放在SessionMiddleware之后:会使用基于会话的存储。'django.middleware.clickjacking.XFrameOptionsMiddleware', #XFrameOptionsMiddleware代码, 是在response添加X-Frame-Options属性. ]
X-Frame-Options有三个值:
- DENY: 浏览器拒绝当前页面加载任何frame页面
- SAMEORIGIN: frame页面的地址只能为同源域名下的页面
- ALLOW-FROM: 允许frame加载的页面地址
4、Django中间件可以定义的五个方法
https://www.cnblogs.com/huchong/p/7819296.html#_label2
5、中间件的应用场景
由于中间件工作在 视图函数执行前、执行后(像不像所有视图函数的装饰器!)适合所有的请求/一部分请求做批量处理
1、做IP限制
放在 中间件类的列表中,阻止某些IP访问了;
2、URL访问过滤
如果用户访问的是login视图(放过)
如果访问其他视图(需要检测是不是有session已经有了放行,没有返回login),这样就省得在 多个视图函数上写装饰器了!
3、缓存(还记得CDN吗?)
客户端请求来了,中间件去缓存看看有没有数据,有直接返回给用户,没有再去逻辑层 执行视图函数
3、django的csrf是如何实现?
1、process_view方法
- 检查视图是否被 @csrf_exempt (免除csrf认证)
- 去请求体或cookie中获取token
情况一:MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware', # 全站使用csrf认证'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] from django.views.decorators.csrf import csrf_exempt @csrf_exempt # 该函数无需认证 def users(request): user_list = ['alex','oldboy'] return HttpResponse(json.dumps((user_list))) 情况二: MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', # 全站不使用csrf认证 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] from django.views.decorators.csrf import csrf_exempt @csrf_protect # 该函数需认证 def users(request): user_list = ['alex','oldboy'] return HttpResponse(json.dumps((user_list)))
2、CBV小知识,csrf时需要使用
- @method_decorator(csrf_exempt)
- 在dispatch方法中(单独方法无效)
方式一:from django.views.decorators.csrf import csrf_exempt,csrf_protectfrom django.utils.decorators import method_decoratorclass StudentsView(View):@method_decorator(csrf_exempt)def dispatch(self, request, *args, **kwargs):return super(StudentsView,self).dispatch(request, *args, **kwargs) def get(self,request,*args,**kwargs): print('get方法') return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def put(self, request, *args, **kwargs): return HttpResponse('PUT') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE') 方式二: from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator @method_decorator(csrf_exempt,name='dispatch') class StudentsView(View): def get(self,request,*args,**kwargs): print('get方法') return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def put(self, request, *args, **kwargs): return HttpResponse('PUT') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE')
总结:- 本质,基于反射来实现- 流程:路由,view,dispatch(反射)- 取消csrf认证(装饰器要加到dispatch方法上且method_decorator装饰)扩展:- csrf - 基于中间件的process_view方法- 装饰器给单独函数进行设置(认证或无需认证)
三、Django中请求的声明周期
https://www.cnblogs.com/renpingsheng/p/7534897.html
四、Django REST framework的请求生命周期
Django REST framework的请求生命周期:https://www.cnblogs.com/renpingsheng/p/7892719.html
转载于:https://www.cnblogs.com/happy-king/p/8607928.html
Django-分页、中间件和请求的声明周期相关推荐
- python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)...
python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页) 一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 fro ...
- Laravel的请求声明周期
声明周期概述# 开始# public/index.php 文件是所有对Laravel应用程序的请求的入口点.而所有的请求都是经由你的Web服务器(Apache/Nginx) 通过配置引导到这个文件.i ...
- Django之中间件,csrf跨站伪造请求,auth认证模块
Django请求生命周期 django的中间件 django的中间件相当于保安,请求的时候要经过django的中间件才能连接django的后端 能用来干什么:能够做网站的全局身份认证,访问频率,权限认 ...
- 浅谈Django的中间件与Python的装饰器
浅谈Django的中间件 与Python的装饰器 一.原理 1.装饰器是Python的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,在执行该 ...
- Django的中间件
Django的中间件 目录 中间件介绍 什么是中间件? 自定义中间件 自定义一个中间件示例 process_request process_response process_view process_ ...
- 2019.03.20 mvt,Django分页
MVT模式 MVT各部分的功能: M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理. V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回响应. T全拼为T ...
- Django 组件- 中间件
11.1 中间件 一.中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨 ...
- JSP→基本语法/静态内容/指令/动作/表达式/小脚本(Scriptlet)/声明/注释、JSP页面声明周期、代码样例、九大隐式内置对象及方法代码样例
JSP(全称JavaServer Pages)是一种动态网页技术标准. 指令 注释 小脚本 声明 表达式 JSP页面声明周期 九九乘法表样例 九大隐式内置对象 out get与post请求方式区别 r ...
- 07 Django组件-中间件
中间件 方式一:函数式:中间件[middleware],也叫钩子方法[钩子函数],hook Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Djang ...
最新文章
- mongodb 事务_初探MongoDB事务机制
- 11.python并发入门(part8 基于线程队列实现生产者消费者模型)
- 调用Com+时提示找不到文件
- 如何将记事本转换.php,记事本怎么变成表格?电脑便签如何将记事内容转化成Excel表格...
- day05 selenium
- Android之Android Studio常用插件
- 未来编程语言的走向_在编程方面我从失败走向成功的过程以及让我成功的原因
- xshell下载及连接Linux
- Forrester:华为云容器是容器混合云最佳选择
- php分解字符串_php怎么把字符串分解成字符
- 怎么调节Ubuntu系统的屏幕亮度
- sql union 和 union all
- 超火的漫画线稿上色AI出新版了!无监督训练,效果更美好 | 代码+Demo
- C#windows服务中的Timer控件的使用
- Confluence介绍与使用
- JVM-绘图展现字节码执行引擎执行过程
- 数据结构07之哈希表
- oracle实现累加,oracle用sum函数实现累加
- 中兴b860刷机运行Linux,全国各地中兴B860A刷机越狱全贴(2016年2月26日更新)
- GridinSoft CHM编辑器3.2.0多语言,轻松快速地翻译CHM电子书
热门文章
- slitaz c语言开发环境,makefile和cmake的简单使用
- 简单又帅气的折纸机器人教程_几张纸做出帅气纸飞机,做法简单飞行速度超快,手工折纸飞机...
- PDE9 wave equation: general solution
- html5 datepicker使用方法,WdatePicker.js时间日期插件的使用方法
- java遍历范型list_Java 集合(1)-- 俯瞰 Java 集合源码以及分类
- 【Python数据分析】数据挖掘建模——分类与预测——回归分析
- 2019腾讯广告算法初赛第一名的模型
- linux下串口抓包,Linux的串行端口 - wrtie()字节到目标设备通过串口
- swing获取文本框内容_Swing 使用 JTable详解
- php devel 5.3.3 26,php-5.3.27安装