Django进阶
前端之家收集整理的这篇文章主要介绍了
Django进阶,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
内容简介:
- cookie介绍
- session介绍
- 分页
- CSRF
- 中间件
- 缓存
- 信号
1、cookie机制
用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。
由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。
用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
说明:request.COOKIES
request.COOKIES[] 获取,不存在则报错,不建议使用
request.COOKIES.get() 获取cookie,不存在返回None,建议使用
=render(request,=redirect(
,value) 关闭浏览器就失效
response.set_signed_cookie(key,value,salt=,...)
===None,cookie失效时间戳(IE requires expires,so set it hasn
path=,Cookie生效的路径,/页面访问
domain===False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖
- 带签名的cookie:设置时候加签,cookie内容是加密的
response.set_signed_cookie(,,salt=<span style="color: #008000;">#<span style="color: #008000;">从请求中获取cookie,salt参数要一致
request.get_signed_cookie(<span style="color: #800000;">'<span style="color: #800000;">username<span style="color: #800000;">',salt=<span style="color: #800000;">'<span style="color: #800000;">adada<span style="color: #800000;">')
- 使用javascript操作cookie,前提不能设置httponly=True(使用js,需要下载引人jquery.cookie.js插件)
request.method===request.COOKIES.get() 获取当前用户
redirect( render(request,,{<span style="color: #0000ff;">def<span style="color: #000000;"> login(request):
<span style="color: #0000ff;">if request.method==<span style="color: #800000;">"<span style="color: #800000;">GET<span style="color: #800000;">"<span style="color: #000000;">:
<span style="color: #0000ff;">return render(request,<span style="color: #800000;">'<span style="color: #800000;">login.html<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">if request.method==<span style="color: #800000;">"<span style="color: #800000;">POST<span style="color: #800000;">"<span style="color: #000000;">:
u=request.POST.get(<span style="color: #800000;">'<span style="color: #800000;">user<span style="color: #800000;">'<span style="color: #000000;">)
p=request.POST.get(<span style="color: #800000;">'<span style="color: #800000;">pwd<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">print<span style="color: #000000;">(u,p)
<span style="color: #0000ff;">if u==<span style="color: #800000;">'<span style="color: #800000;">admin<span style="color: #800000;">' <span style="color: #0000ff;">and p==<span style="color: #800000;">'<span style="color: #800000;">admin<span style="color: #800000;">'<span style="color: #000000;">:
response=redirect(<span style="color: #800000;">'<span style="color: #800000;">/app01/index/<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #008000;">#<span style="color: #008000;">response.set_cookie('username',u,max_age=60*60)#设置一个小时以后cookie失效
<span style="color: #0000ff;">import<span style="color: #000000;"> datetime
current_date=<span style="color: #000000;">datetime.datetime.now()
expre_date=current_date+datetime.timedelta(seconds=5<span style="color: #000000;">)
response.set_cookie(<span style="color: #800000;">'<span style="color: #800000;">username<span style="color: #800000;">',expires=expre_date) <span style="color: #008000;">#<span style="color: #008000;"> 设置5秒后cookie过期
<span style="color: #0000ff;">return<span style="color: #000000;"> response
<span style="color: #0000ff;">else<span style="color: #000000;">:
<span style="color: #0000ff;">return redirect(<span style="color: #800000;">'<span style="color: #800000;">/app01/login/<span style="color: #800000;">')
- 示例代码二:基于Cookie实现定制显示数据条数(包含juery操作cookie)
模版代码:
Meta
Title
{{ row }}
显示条目数:
10
30
50
100
获取当前选择的值
})
<span style="color: #0000ff;"></<span style="color: #800000;">script<span style="color: #0000ff;">>
<span style="color: #0000ff;"></<span style="color: #800000;">body<span style="color: #0000ff;">>
<span style="color: #0000ff;"></<span style="color: #800000;">html<span style="color: #0000ff;">>
视图代码:
.utils request.method=== int(request.GET.get(,1)) 获取不到默认设置为1
page_num=request.COOKIES.get(== page.PagiNation(current_index=current_index,data_num=500,page_num==mypage.page_str(= render(request,,{:data,:page_str})
登录验证装饰器
基础篇中的django视图提到了,对于view函数中我们可以定义两种视图,一种是函数(FBV),一种是类(CBV)
所以对于认证的装饰器也有两种:
inner(reqeust,*args,**= reqeust.COOKIES.get( redirect( func(reqeust,**<span style="color: #008000;">#<span style="color: #008000;">装饰需要登录验证的函数
<span style="color: #000000;">@auth
<span style="color: #0000ff;">def<span style="color: #000000;"> index(reqeust):<span style="color: #0000ff;">return render(reqeust,{<span style="color: #800000;">'<span style="color: #800000;">current_user<span style="color: #800000;">': v})
inner(reqeust,**<span style="color: #008000;">#<span style="color: #008000;">使用装饰器,方法有三种
<span style="color: #0000ff;">from
django <span style="color: #0000ff;">import<span style="color: #000000;"> views
<span style="color: #0000ff;">from django.utils.decorators <span style="color: #0000ff;">import<span style="color: #000000;"> method_decorator
@method_decorator(auth,name=<span style="color: #800000;">'<span style="color: #800000;">dispatch<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #008000;">#<span style="color: #008000;"> 第三种方法,name="dispatch",就是给dispatch方法加上此装饰器,作用在于在执行post、get方法之前就验证,避免在给post和get方法加装饰器
<span style="color: #0000ff;">class<span style="color: #000000;"> Order(views.View):
<span style="color: #008000;">#<span style="color: #008000;"> @method_decorator(auth) # 第二种方法,作用等同于等三种
<span style="color: #008000;">#<span style="color: #008000;"> def dispatch(self,request,kwargs):
<span style="color: #008000;">#<span style="color: #008000;"> return super(Order,self).dispatch(request,kwargs)
<span style="color: #008000;">#<span style="color: #008000;"> @method_decorator(auth) # 第一种方法,作用可以用针对性,可以只给get方法加装饰器
<span style="color: #0000ff;">def<span style="color: #000000;"> get(self,reqeust):<span style="color: #0000ff;">return render(reqeust,{<span style="color: #800000;">'<span style="color: #800000;">current_user<span style="color: #800000;">'<span style="color: #000000;">: v})
<span style="color: #0000ff;">def<span style="color: #000000;"> post(self,{<span style="color: #800000;">'<span style="color: #800000;">current_user<span style="color: #800000;">': v})
<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0">
<tr>
<td><span style="font-size: 16px;">二、session介绍</td>
</tr></table>
1、session机制
除了使用Cookie,Web应用程序中还经常使用Session来记录客户端状态。,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。
2、session工作原理
查询客户档案表就可以了。
3、Django中使用session
获取session值
request.session[] 获取,不存在则包错,不建议使用
request.session[] 获取,不存在返回None,建议使用
<span style="color: #008000;">#
<span style="color: #008000;">设置session
request.session[<span style="color: #800000;">'<span style="color: #800000;">k1<span style="color: #800000;">']=<span style="color: #800000;">'<span style="color: #800000;">wd<span style="color: #800000;">'<span style="color: #000000;">
request.session.setdefault(<span style="color: #800000;">'<span style="color: #800000;">key<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">value<span style="color: #800000;">') <span style="color: #008000;">#<span style="color: #008000;">存在则不设置
<span style="color: #008000;">#<span style="color: #008000;">删除某个session键值
<span style="color: #0000ff;">del request.session[<span style="color: #800000;">'<span style="color: #800000;">key<span style="color: #800000;">'<span style="color: #000000;">]
<span style="color: #008000;">#<span style="color: #008000;">循环session中的字典,与字典循环类似
request.session.keys() <span style="color: #008000;">#<span style="color: #008000;">所有的key
request.session.values() <span style="color: #008000;">#<span style="color: #008000;">所有的value
request.session.items() <span style="color: #008000;">#<span style="color: #008000;">k,v形式
request.session.iterkeys() <span style="color: #008000;">#<span style="color: #008000;">所有的key
request.session.itervalues() <span style="color: #008000;">#<span style="color: #008000;">所有的value
request.session.iteritems() <span style="color: #008000;">#<span style="color: #008000;">k,v形式
<span style="color: #008000;">#<span style="color: #008000;">获取用户session中的随机字符串
<span style="color: #000000;">request.session.session_key
<span style="color: #008000;">#<span style="color: #008000;">删除所有session失效日期小于当前日志的数据(删除同一用户制造的脏数据)
<span style="color: #000000;">request.session.clear_expired()
<span style="color: #008000;">#<span style="color: #008000;">删除当前用户的所有session数据(在用户退出登录时候使用)
request.session.delete(<span style="color: #800000;">'<span style="color: #800000;">用户随机字符串<span style="color: #800000;">')<span style="color: #008000;">#<span style="color: #008000;">使用比较麻烦,因为还的获取用户随机字符串
request.session.clear()<span style="color: #008000;">#<span style="color: #008000;">该方法会先获取用户的随机字符串,然后把其对应的所有数据删除,推荐注销(退出登录)时候使用<span style="color: #008000;">
<span style="color: #008000;">设置seesion失效时间
<span style="color: #000000;">request.session.set_expiry(value)
<span style="color: #000000;"> 如果value是个整数,session会在些秒数后失效。
<span style="color: #000000;"> 如果value是个datatime或timedelta,session就会在这个时间后失效。
<span style="color: #000000;"> 如果value是0,用户关闭浏览器session就会失效。
如果value是None,session会依赖全局session失效策略,默认全局两周失效
4、Django中session相关配置
django默认session存储位置在数据库表中,表名为django_session,当然django还提供了多样化存储session,有以下几种:
1、数据库Session配置
SESSION_ENGINE </span>= <span style="color: #800000;">'</span><span style="color: #800000;">django.contrib.sessions.backends.db</span><span style="color: #800000;">'</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 引擎(默认)</span>
<span style="color: #000000;">
SESSION_COOKIE_NAME =
<span style="color: #800000;">"<span style="color: #800000;">sessionid<span style="color: #800000;">" <span style="color: #008000;">#<span style="color: #008000;"> Session的cookie保存在浏览器上时的key,即:sessionid=
随机字符串(默认
SESSION_COOKIE_PATH = <span style="color: #800000;">"<span style="color: #800000;">/<span style="color: #800000;">" <span style="color: #008000;">#<span style="color: #008000;"> Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None <span style="color: #008000;">#<span style="color: #008000;"> Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False <span style="color: #008000;">#<span style="color: #008000;"> 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True <span style="color: #008000;">#<span style="color: #008000;"> 是否Session的cookie只
支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 <span style="color: #008000;">#<span style="color: #008000;"> Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False <span style="color: #008000;">#<span style="color: #008000;"> 是否
关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False <span style="color: #008000;">#<span style="color: #008000;"> 是否每次请求都保存Session,默认
修改之后才保存(默认),最好设置为True,这样超时时间都是最新的
2、缓存session(memchache)配置
SESSION_ENGINE </span>= <span style="color: #800000;">'</span><span style="color: #800000;">django.contrib.sessions.backends.cache</span><span style="color: #800000;">'</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 引擎</span>
SESSION_CACHE_ALIAS = <span style="color: #800000;">'</span><span style="color: #800000;">default</span><span style="color: #800000;">'</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置</span>
<span style="color: #000000;">
SESSION_COOKIE_NAME = </span><span style="color: #800000;">"</span><span style="color: #800000;">sessionid</span><span style="color: #800000;">"</span> <span style="color: #008000;">#</span><span style="color: #008000;"> Session的cookie保存在浏览器上时的key,即:sessionid=<a href="/tag/suiji/" target="_blank" class="keywords">随机</a>字符串</span>
SESSION_COOKIE_PATH = <span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span> <span style="color: #008000;">#</span><span style="color: #008000;"> Session的cookie保存的路径</span>
SESSION_COOKIE_DOMAIN = None <span style="color: #008000;">#</span><span style="color: #008000;"> Session的cookie保存的域名</span>
SESSION_COOKIE_SECURE = False <span style="color: #008000;">#</span><span style="color: #008000;"> 是否Https传输cookie</span>
SESSION_COOKIE_HTTPONLY = True <span style="color: #008000;">#</span><span style="color: #008000;"> 是否Session的cookie只<a href="/tag/zhichi/" target="_blank" class="keywords">支持</a>http传输</span>
SESSION_COOKIE_AGE = 1209600 <span style="color: #008000;">#</span><span style="color: #008000;"> Session的cookie失效日期(2周)</span>
SESSION_EXPIRE_AT_BROWSER_CLOSE = False <span style="color: #008000;">#</span><span style="color: #008000;"> 是否<a href="/tag/guanbi/" target="_blank" class="keywords">关闭</a>浏览器使得Session过期</span>
SESSION_SAVE_EVERY_REQUEST = False <span style="color: #008000;">#</span><span style="color: #008000;"> 是否每次请求都保存Session,默认<a href="/tag/xiugai/" target="_blank" class="keywords">修改</a>之后才保存</span></pre>
3、文件session配置
SESSION_ENGINE </span>= <span style="color: #800000;">'</span><span style="color: #800000;">django.contrib.sessions.backends.file</span><span style="color: #800000;">'</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 引擎</span>
SESSION_FILE_PATH = None <span style="color: #008000;">#</span><span style="color: #008000;"> 缓存<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>路径,如果为None,则使用tempfile模块<a href="/tag/huoqu/" target="_blank" class="keywords">获取</a>一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T</span>
4、数据库+缓存session配置
4、缓存+
数据库Session
数据库用于做持久化,缓存用于提高效率
a. 配置 settings.py
SESSION_ENGINE </span>= <span style="color: #800000;">'</span><span style="color: #800000;">django.contrib.sessions.backends.cached_db</span><span style="color: #800000;">'</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 引擎</span></pre>
5、加密cookie session配置
SESSION_ENGINE </span>= <span style="color: #800000;">'</span><span style="color: #800000;">django.contrib.sessions.backends.signed_cookies</span><span style="color: #800000;">'</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 引擎</span></pre>
5、基于session的用户验证装饰器
wrap(request,**跳转到指定页面
request.session.get( redirect( func(request,** wrap
6、session和cookie区别
1.作用
当你要登录京东和天猫的时候,当登录成功的时候。我点击其他功能例如购物车 订单等功能的时候是如何判断你已经登录的呢。那就是用的cookie或者session功能。
2.区别
cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
3.session流程
1、自动生成一段字符串
2、将字符串发送到客户端的浏览器,同时把字符串当做key放在session里。(可以理解为session就是一个字典)
3、在用户的session对应的value里设置任意值
<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0">
<tr>
<td><span style="font-size: 16px;">三、分页</td>
</tr>
</table>
一、Django自带的分页
视图:
django.shortcuts django.core.paginator L =<span style="color: #000000;"> []
<span style="color: #0000ff;">for i <span style="color: #0000ff;">in range(999<span style="color: #000000;">):
L.append(i)
<span style="color: #0000ff;">def<span style="color: #000000;"> index(request):
current_page = request.GET.get(<span style="color: #800000;">'<span style="color: #800000;">p<span style="color: #800000;">'<span style="color: #000000;">)
paginator </span>= Paginator(L,10<span style="color: #000000;">)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> per_page: 每页<a href="/tag/xianshi/" target="_blank" class="keywords">显示</a>条目<a href="/tag/shuliang/" target="_blank" class="keywords">数量</a></span>
<span style="color: #008000;">#</span><span style="color: #008000;"> count: 数据总个数</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> num_pages:总页数</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> page_range:总页数的索引范围,如: (1,10),(1,200)</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> page: page对象</span>
<span style="color: #0000ff;">try</span><span style="color: #000000;">:
posts </span>=<span style="color: #000000;"> paginator.page(current_page)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> has_next 是否有<a href="/tag/xiayiye/" target="_blank" class="keywords">下一页</a></span>
<span style="color: #008000;">#</span><span style="color: #008000;"> next_page_number <a href="/tag/xiayiye/" target="_blank" class="keywords">下一页</a><a href="/tag/yema/" target="_blank" class="keywords">页码</a></span>
<span style="color: #008000;">#</span><span style="color: #008000;"> has_prev<a href="/tag/IoU/" target="_blank" class="keywords">IoU</a>s 是否有<a href="/tag/shangyiye/" target="_blank" class="keywords">上一页</a></span>
<span style="color: #008000;">#</span><span style="color: #008000;"> prev<a href="/tag/IoU/" target="_blank" class="keywords">IoU</a>s_page_number <a href="/tag/shangyiye/" target="_blank" class="keywords">上一页</a><a href="/tag/yema/" target="_blank" class="keywords">页码</a></span>
<span style="color: #008000;">#</span><span style="color: #008000;"> object_list <a href="/tag/fenye/" target="_blank" class="keywords">分页</a>之后的数据列表</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> number 当前页</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> paginator paginator对象</span>
<span style="color: #0000ff;">except</span><span style="color: #000000;"> PageNotAnInteger:
posts </span>= paginator.page(1<span style="color: #000000;">)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EmptyPage:
posts </span>=<span style="color: #000000;"> paginator.page(paginator.num_pages)
</span><span style="color: #0000ff;">return</span> render(request,{<span style="color: #800000;">'</span><span style="color: #800000;">posts</span><span style="color: #800000;">'</span>: posts})</pre>
模版文件
>
<Meta charset=>
% item posts %- {{ item }}
% endfor %
<div <span style="color: #0000ff;">class
=<span style="color: #800000;">"<span style="color: #800000;">pagination<span style="color: #800000;">">
<span <span style="color: #0000ff;">class=<span style="color: #800000;">"<span style="color: #800000;">step-links<span style="color: #800000;">"><span style="color: #000000;">
{% <span style="color: #0000ff;">if posts.has_prev
IoUs %<span style="color: #000000;">}
<a href=<span style="color: #800000;">"<span style="color: #800000;">?p={{ posts.previous_page_number }}<span style="color: #800000;">">Previous<span style="color: #000000;">
{% endif %<span style="color: #000000;">}
<span <span style="color: #0000ff;">class=<span style="color: #800000;">"<span style="color: #800000;">current<span style="color: #800000;">"><span style="color: #000000;">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
<span style="color: #000000;">
{% <span style="color: #0000ff;">if posts.has_next %<span style="color: #000000;">}
<a href=<span style="color: #800000;">"<span style="color: #800000;">?p={{ posts.next_page_number }}<span style="color: #800000;">">Next<span style="color: #000000;">
{% endif %<span style="color: #000000;">}
扩展内置分页:
django.shortcuts django.core.paginator <span style="color: #0000ff;">class<span style="color: #000000;"> CustomPaginator(Paginator):
<span style="color: #0000ff;">def <span style="color: #800080;">init(self,current_page,max_pager_num,*<span style="color: #000000;">kwargs):
<span style="color: #800000;">"""<span style="color: #800000;">
:param current_page: 当前页
:param max_pager_num:最多
显示的
页码个数
:param args:
:param kwargs:
:return:
<span style="color: #800000;">"""<span style="color: #000000;">
self.current_page =<span style="color: #000000;"> int(current_page)
self.max_pager_num =<span style="color: #000000;"> max_pager_num
super(CustomPaginator,self).<span style="color: #800080;">
init(args,**<span style="color: #000000;">kwargs)
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> page_num_range(self):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> <a href="/tag/dangqianyemian/" target="_blank" class="keywords">当前页面</a></span>
<span style="color: #008000;">#</span><span style="color: #008000;"> self.current_page</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> 总页数</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> self.num_pages</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> 最多<a href="/tag/xianshi/" target="_blank" class="keywords">显示</a>的<a href="/tag/yema/" target="_blank" class="keywords">页码</a>个数</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> self.max_pager_num</span>
<span style="color: #0000ff;">print</span>(1<span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> self.num_pages <<span style="color: #000000;"> self.max_pager_num:
</span><span style="color: #0000ff;">return</span> range(1,self.num_pages + 1<span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span>(2<span style="color: #000000;">)
part </span>= int(self.max_pager_num / 2<span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> self.current_page - part < 1<span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span> range(1,self.max_pager_num + 1<span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span>(3<span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> self.current_page + part ><span style="color: #000000;"> self.num_pages:
</span><span style="color: #0000ff;">return</span> range(self.num_pages + 1 - self.max_pager_num,self.num_pages + 1<span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span>(4<span style="color: #000000;">)
</span><span style="color: #0000ff;">return</span> range(self.current_page - part,self.current_page + part + 1<span style="color: #000000;">)
L =<span style="color: #000000;"> []
<span style="color: #0000ff;">for i <span style="color: #0000ff;">in range(999<span style="color: #000000;">):
L.append(i)
<span style="color: #0000ff;">def<span style="color: #000000;"> index(request):
current_page = request.GET.get(<span style="color: #800000;">'<span style="color: #800000;">p<span style="color: #800000;">'<span style="color: #000000;">)
paginator = CustomPaginator(current_page,11,L,200)
<span style="color: #008000;">#<span style="color: #008000;"> page: page对象
<span style="color: #0000ff;">try<span style="color: #000000;">:
posts =<span style="color: #000000;"> paginator.page(current_page)
<span style="color: #008000;">#<span style="color: #008000;"> has_next 是否有下一页
<span style="color: #008000;">#<span style="color: #008000;"> next_page_number 下一页页码
<span style="color: #008000;">#<span style="color: #008000;"> has_prevIoUs 是否有上一页
<span style="color: #008000;">#<span style="color: #008000;"> prevIoUs_page_number 上一页页码
<span style="color: #008000;">#<span style="color: #008000;"> object_list 分页之后的数据列表
<span style="color: #008000;">#<span style="color: #008000;"> number 当前页
<span style="color: #008000;">#<span style="color: #008000;"> paginator paginator对象
<span style="color: #0000ff;">except<span style="color: #000000;"> PageNotAnInteger:
posts = paginator.page(1<span style="color: #000000;">)
<span style="color: #0000ff;">except<span style="color: #000000;"> EmptyPage:
posts =<span style="color: #000000;"> paginator.page(paginator.num_pages)
</span><span style="color: #0000ff;">return</span> render(request,{<span style="color: #800000;">'</span><span style="color: #800000;">posts</span><span style="color: #800000;">'</span>: posts})</pre>
分页
>
<Meta charset=>
% item posts %- {{ item }}
% endfor %
<div <span style="color: #0000ff;">class
=<span style="color: #800000;">"<span style="color: #800000;">pagination<span style="color: #800000;">">
<span <span style="color: #0000ff;">class=<span style="color: #800000;">"<span style="color: #800000;">step-links<span style="color: #800000;">"><span style="color: #000000;">
{% <span style="color: #0000ff;">if posts.has_prev
IoUs %<span style="color: #000000;">}
<a href=<span style="color: #800000;">"<span style="color: #800000;">?p={{ posts.previous_page_number }}<span style="color: #800000;">">Previous<span style="color: #000000;">
{% endif %<span style="color: #000000;">}
{</span>% <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span> posts.paginator.page_num_range %<span style="color: #000000;">}
</span><a href=<span style="color: #800000;">"</span><span style="color: #800000;">?p={{ i }}</span><span style="color: #800000;">"</span>>{{ i }}</a><span style="color: #000000;">
{</span>% endfor %<span style="color: #000000;">}
{</span>% <span style="color: #0000ff;">if</span> posts.has_next %<span style="color: #000000;">}
</span><a href=<span style="color: #800000;">"</span><span style="color: #800000;">?p={{ posts.next_page_number }}</span><span style="color: #800000;">"</span>>Next</a><span style="color: #000000;">
{</span>% endif %<span style="color: #000000;">}
<span <span style="color: #0000ff;">class=<span style="color: #800000;">"<span style="color: #800000;">current<span style="color: #800000;">"><span style="color: #000000;">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
分页html模版
先介绍下XSS(跨站脚本攻击):
跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
原因:我们在自定义分页时候会额外的给页面添加HTML代码,默认Django会认为这些代码是不安全的属于XSS攻击,所以会当作字符串处理不会作为HTML代码显示,所以我们需要告诉Django这个代码是安全的。
方法有两种:
1.在html模板中方法:
{{ html_str|safe }}
2.在后台函数中使用
django.utils.safestring =mark_safe(html_str)
3.自定义分页(可以作为一个工具类,作为公共模块使用)
django.utils.safestring (self,current_index,data_num,page_num=10,show_index_num=10显示的页码
:param data_num: 显示的内容的总条目数
:param page_num: 每页显示的内容的条目数
:param show_index_num: 每一页显示的页码数目
==== start(self): 获取显示的页码起始位置
(self.current_index - 1) * end(self): 获取显示页码的终止位置
self.current_index * total_index(self): 获取显示页码的总页码数量
math.ceil(self.data_num /</span><span style="color: #0000ff;">def</span> page_str(self,base_url): <span style="color: #008000;">#</span><span style="color: #008000;"><a href="/tag/huoqu/" target="_blank" class="keywords">获取</a>最后展现的a<a href="/tag/biaoqian/" target="_blank" class="keywords">标签</a>字符串</span>
<span style="color: #800000;">'''</span><span style="color: #800000;">
:param base_url: <a href="/tag/tiaozhuan/" target="_blank" class="keywords">跳转</a><a href="/tag/lianjiedizhi/" target="_blank" class="keywords">链接地址</a>
:return: 返回django认可的<a href="/tag/HTMLdaima/" target="_blank" class="keywords">HTML代码</a>
</span><span style="color: #800000;">'''</span><span style="color: #000000;">
page_list</span>=<span style="color: #000000;">[]
half_index </span>= int(self.show_index_num/2) <span style="color: #008000;">#</span><span style="color: #008000;"> <a href="/tag/xianshi/" target="_blank" class="keywords">显示</a><a href="/tag/yema/" target="_blank" class="keywords">页码</a>数的一半</span>
<span style="color: #0000ff;">if</span> self.total_index < self.show_index_num: <span style="color: #008000;">#</span><span style="color: #008000;"> 起始<a href="/tag/yema/" target="_blank" class="keywords">页码</a>小于<a href="/tag/xianshi/" target="_blank" class="keywords">显示</a>的<a href="/tag/yema/" target="_blank" class="keywords">页码</a>数目,结束<a href="/tag/yema/" target="_blank" class="keywords">页码</a>则为总<a href="/tag/xianshi/" target="_blank" class="keywords">显示</a>页数</span>
start_index = 1<span style="color: #000000;">
end_index </span>= self.total_index+1
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> self.current_index < half_index <span style="color: #0000ff;">or</span> self.current_index == half_index:<span style="color: #008000;">#</span><span style="color: #008000;">当前<a href="/tag/yema/" target="_blank" class="keywords">页码</a>小于或等于<a href="/tag/xianshi/" target="_blank" class="keywords">显示</a><a href="/tag/yema/" target="_blank" class="keywords">页码</a><a href="/tag/shuliang/" target="_blank" class="keywords">数量</a>的一半</span>
start_index = 1<span style="color: #000000;">
end_index </span>= self.show_index_num + 1
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
start_index </span>= self.current_index - half_index + 1
<span style="color: #0000ff;">if</span> self.current_index + half_index > self.total_index:<span style="color: #008000;">#</span><span style="color: #008000;">当前<a href="/tag/yema/" target="_blank" class="keywords">页码</a>+<a href="/tag/xianshi/" target="_blank" class="keywords">显示</a><a href="/tag/yema/" target="_blank" class="keywords">页码</a>数的一半大于总的<a href="/tag/yema/" target="_blank" class="keywords">页码</a>数目</span>
start_index = self.total_index - self.show_index_num + 1<span style="color: #000000;">
end_index </span>= self.total_index + 1
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
end_index </span>= self.current_index + half_index + 1
<span style="color: #0000ff;">if</span> self.current_index == 1<span style="color: #000000;">:
page_list.append(</span><span style="color: #800000;">'</span><span style="color: #800000;"><a class="pg-a" href="javascript:void(0);">上一页</a></span><span style="color: #800000;">'</span>)<span style="color: #008000;">#</span><span style="color: #008000;">javascript:void(0)意思是不错任何操作</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
page_list.append(</span><span style="color: #800000;">'</span><span style="color: #800000;"><a href=%s?p=%s class="pg-a alive">上一页</a></span><span style="color: #800000;">'</span> % (base_url,self.current_index - 1<span style="color: #000000;">,))
</span><span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span><span style="color: #000000;"> range(start_index,end_index):
</span><span style="color: #0000ff;">if</span> i ==<span style="color: #000000;"> self.current_index:
page_url </span>= <span style="color: #800000;">'</span><span style="color: #800000;"><a href=%s?p=%s class="pg-a alive">%s</a></span><span style="color: #800000;">'</span> %<span style="color: #000000;"> (base_url,i,i)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
page_url </span>= <span style="color: #800000;">'</span><span style="color: #800000;"><a href=%s?p=%s class="pg-a ">%s</a></span><span style="color: #800000;">'</span> %<span style="color: #000000;"> (base_url,i)
page_list.append(page_url)
</span><span style="color: #0000ff;">if</span> self.current_index ==<span style="color: #000000;"> self.total_index:
page_list.append(</span><span style="color: #800000;">'</span><span style="color: #800000;"><a class="pg-a" href="javascript:void(0);">下一页</a></span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
page_list.append(</span><span style="color: #800000;">'</span><span style="color: #800000;"><a href=%s?p=%s class="pg-a alive">下一页</a></span><span style="color: #800000;">'</span> % (base_url,self.current_index + 1<span style="color: #000000;">,))
page_str </span>= mark_safe(<span style="color: #800000;">""</span><span style="color: #000000;">.join(page_list))
</span><span style="color: #0000ff;">return</span> page_str</pre>
分页
4.使用示例
.utils request.method=== int(request.GET.get(,1)) 获取不到默认设置为1
mypage = page.PagiNation(current_index=current_index,data_num=500=mypage.page_str( render(request,:page_str})
<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0">
<tr>
<td><span style="font-size: 16px;">四、跨站请求伪造(CSRF)</td>
</tr></table>
1、简介:
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比更具危险性。
2、Django中防护CSRF模块
Django中的CSRF防护是通过中间件的手段来达到防护的目的,中间件路径:django.middleware.csrf.CsrfViewMiddleware ,配置文件settings中指定了全局配置,单也可以单独针对某个views函数来配置,具体配置:
中间件 django.middleware.csrf.CsrfViewMiddleware
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
TIPS:配置模块导入from django.views.decorators.csrf import csrf_exempt,csrf_protect
3、原理
当我们向Django后台post数据时,在Django中防护CSRF是通过获取用户请求头中是否含有X-CSRFtoken请求头所对应的随机字符串(),如果有并且是正确的,则可以提交,否则则返回Forbidden(403)错误。
4、提交数据
form表单提交数据:在form表单中加上{% csrf_token %},默认会在表单中生成隐藏的input标签
提交过程:
用户访问页面,{% csrf_token %}模版语言生成CSRF随机随机字符串,并且cookie中也生成了该字符串,当用户提交数据时候cookie中会带着这个字符串进行提交,如果没有该字符串则提交失败
通过ajax提交数据时候,和form表单一样,我们提交数据时需要在请求头中加上X-CSRFtoken,所以提交的时候需要利用js获取cookie中的该随机字符串进行提交:
$("#btn").click("/login/""POST""user":"wd","pwd":"1234""X-CSRFtoken":$.cookie("csrftoken")},
success: }
})
})</span></pre>
但是如果页面中有多个ajax请求的话就在每个ajax中添加headers信息,所以可以在页面框架加载完时候通过以下方式提交,这样会在页面中所有ajax提交数据之前加上csrftoken信息
xhr.setRequestHeader("X-CSRFtoken",$.cookie("csrftoken"
最后,一般我们只希望post提交数据时候才会使用csrf验证,所以官网推荐
(/^(GET|HEAD|OPTIONS|TRACE)$/方法,返回true或者flase
}
$.ajaxSetup({
beforeSend: (!csrfSafeMethod(settings.type) && !"X-CSRFToken"
5、Django后台验证过程
csrf在前端的key为X-CSRFtoken,通过form或者ajax提交到后台,后端的django会自动添加HTTP_,并且最后为的key变成HTTP_X_CSRFtoken,如果随机字符串通过验证则数据提交,否则报错(403)。
1、简介
django中的中间件,在其他web框架中,有的叫管道或者httphandle,Django中很多功能都是通过中间件实现的,实际上中间件就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。在工程中的settings.py中由变量MIDDLEWARE控制,请求从上到下依次穿过中间件,每个中间件中都可以有5个方法:
- process_request(self,request)#请求最开始执行的方法
- process_response(self,response)#请求返回时候执行的方法
- process_view(self,callback,callback_args,callback_kwargs)#请求到达views视图之前执行的方法
- process_exception(self,exception) # 默认不执行,除非Views方法出错
- process_template_response(self,response) # 默认不执行,除非Views中的函数返回的对象中,具有render方法(区别于模板渲染的render)

2、请求在中间件中的方法请求过程
- 用户请求先中间件,由上到下先后执行每个中间件process_request方法;
- 执行完每个中间件的process_request方法之后,请求到达urls路由关系映射;
- 到达urls路由映射以后,由下至上执行每个中间件的process_views方法;
- 执行完process_views,请求到达views函数,此时若views函数有错误信息,则由下到上执行process_exception方法,直到错误被抓住停止,都没有抓住页面包错;
- 如果views函数中没有出错,那么请求由下到上执行每个中间件的process_response方法,最后响应客户;
大致的请求过程:

自定义中间件,我们至少包括两个方法,一个是process_request,还有一个是process_response,创建一个py文件,在工程中创建MyMiddleWare目录(与tempates同级),创建文件md.py,注意使用process_response必须返回response:
django.utils.deprecation django.shortcuts <span style="color: #008000;">#<span style="color: #008000;">中间件1
<span style="color: #0000ff;">class<span style="color: #000000;"> Row1(MiddlewareMixin):
<span style="color: #0000ff;">def<span style="color: #000000;"> process_request(self,request):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">中间件1请求<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">def<span style="color: #000000;"> process_response(self,response):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">中间件1返回<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">return<span style="color: #000000;"> response
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> process_view(self,callback_kwargs):
</span><span style="color: #0000ff;">print</span>(<span style="color: #800000;">"</span><span style="color: #800000;">中间件1view</span><span style="color: #800000;">"</span><span style="color: #000000;">)
<span style="color: #008000;">#<span style="color: #008000;">中间件2
<span style="color: #0000ff;">class<span style="color: #000000;"> Row2(MiddlewareMixin):
<span style="color: #0000ff;">def<span style="color: #000000;"> process_request(self,request):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">中间件2请求<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #008000;">#<span style="color: #008000;"> return HttpResponse("走")
<span style="color: #0000ff;">def<span style="color: #000000;"> process_response(self,response):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">中间件2返回<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">return<span style="color: #000000;"> response
<span style="color: #0000ff;">def<span style="color: #000000;"> process_view(self,callback_kwargs):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">中间件2view<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #008000;">#<span style="color: #008000;">中间件3
<span style="color: #0000ff;">class<span style="color: #000000;"> Row3(MiddlewareMixin):
<span style="color: #0000ff;">def<span style="color: #000000;"> process_request(self,request):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">中间件3请求<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">def<span style="color: #000000;"> process_response(self,response):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">中间件3返回<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">return<span style="color: #000000;"> response
<span style="color: #0000ff;">def<span style="color: #000000;"> process_view(self,callback_kwargs):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">中间件3view<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">def<span style="color: #000000;"> process_exception(self,exception):
<span style="color: #800000;">"""<span style="color: #800000;">只有出现异常时才会执行<span style="color: #800000;">"""
<span style="color: #0000ff;">if<span style="color: #000000;"> isinstance(exception,ValueError):
<span style="color: #0000ff;">return HttpResponse(<span style="color: #800000;">'<span style="color: #800000;">出现异常》。。<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">elif<span style="color: #000000;"> isinstance(exception,TemplateDoesNotExist):
<span style="color: #0000ff;">print<span style="color: #000000;">(request.path_info)
<span style="color: #0000ff;">return render(request,<span style="color: #800000;">"<span style="color: #800000;">404.html<span style="color: #800000;">"<span style="color: #000000;">)
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> process_template_response(self,response):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">如果Views中的<a href="/tag/hanshu/" target="_blank" class="keywords">函数</a>返回的对象中,具有render<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a>才会执行</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">print</span>(<span style="color: #800000;">'</span><span style="color: #800000;">-----------------------</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">return</span> response</pre>
注册中间件:使用中间件需要在settings.py中注册你的中间件,配置就是你的中间件文件路径
MIDDLEWARE =
4、版本变化
上面所说的Django中间件请求过程是在1.10版本之后(包括1.10),而在1.10版本之前稍微有些区别,区别就在请求异常时候,方法返回给用户请求,而在1.10以前的版本请求返回是从最底部的中间件的process_response方法向上返回
简介
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者memchazhe中之前缓存的内容拿到,并返回。
Django提供了6种缓存方式:
- 开发调试
- 内存
- 文件
- 数据库
- Memcache缓存(python-memcached模块)
- Memcache缓存(pylibmc模块)
缓存方式配置
通用配置
CACHES =: ,
: 300,
: 300,
: 3,
: ,
: 1,
函数名 生成key的函数(默认函数会生成为:【前缀:版本:key】)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> <a href="/tag/zidingyi/" target="_blank" class="keywords">自定义</a>key</span>
<span style="color: #0000ff;">def</span><span style="color: #000000;"> default_key_func(key,key_prefix,version):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">
Default function to generate keys.
Constructs the key used by all other methods. By default it prepends
the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
function with custom key making behavior.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">return</span> <span style="color: #800000;">'</span><span style="color: #800000;">%s:%s:%s</span><span style="color: #800000;">'</span> %<span style="color: #000000;"> (key_prefix,version,key)
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_key_func(key_func):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">
Function to decide which key function to use.
Defaults to ``default_key_func``.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> key_func <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> callable(key_func):
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> key_func
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> import_string(key_func)
</span><span style="color: #0000ff;">return</span> default_key_func</pre>
使用内存
内容保存至内存的变量中
CACHES =: : </span><span style="color: #008000;">#</span><span style="color: #008000;"> 注:其他配置同开发调试版本</span></pre>
使用文件
使用数据库
内容保存至数据库
<span style="color: #008000;">#</span><span style="color: #008000;"> 配置:</span>
CACHES =<span style="color: #000000;"> {
</span><span style="color: #800000;">'</span><span style="color: #800000;">default</span><span style="color: #800000;">'</span><span style="color: #000000;">: {
</span><span style="color: #800000;">'</span><span style="color: #800000;">BACKEND</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">django.core.cache.backends.db.DatabaseCache</span><span style="color: #800000;">'</span><span style="color: #000000;">,</span><span style="color: #800000;">'</span><span style="color: #800000;">LOCATION</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">my_cache_table</span><span style="color: #800000;">'</span>,<span style="color: #008000;">#</span><span style="color: #008000;"> <a href="/tag/shujuku/" target="_blank" class="keywords">数据库</a>表</span>
<span style="color: #000000;"> }
}
</span><span style="color: #008000;">#</span><span style="color: #008000;"> 注:执行创建表命令 python manage.py createcachetable</span></pre>
使用memcache缓存(python-memcached模块)
=: : CACHES </span>=<span style="color: #000000;"> {
</span><span style="color: #800000;">'</span><span style="color: #800000;">default</span><span style="color: #800000;">'</span><span style="color: #000000;">: {
</span><span style="color: #800000;">'</span><span style="color: #800000;">BACKEND</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">django.core.cache.backends.memcached.MemcachedCache</span><span style="color: #800000;">'</span><span style="color: #000000;">,</span><span style="color: #800000;">'</span><span style="color: #800000;">LOCATION</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">unix:/tmp/memcached.sock</span><span style="color: #800000;">'</span><span style="color: #000000;">,}
}
CACHES </span>=<span style="color: #000000;"> {
</span><span style="color: #800000;">'</span><span style="color: #800000;">default</span><span style="color: #800000;">'</span><span style="color: #000000;">: {
</span><span style="color: #800000;">'</span><span style="color: #800000;">BACKEND</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">django.core.cache.backends.memcached.MemcachedCache</span><span style="color: #800000;">'</span><span style="color: #000000;">,</span><span style="color: #800000;">'</span><span style="color: #800000;">LOCATION</span><span style="color: #800000;">'</span><span style="color: #000000;">: [
</span><span style="color: #800000;">'</span><span style="color: #800000;">172.19.26.240:11211</span><span style="color: #800000;">'</span><span style="color: #000000;">,</span><span style="color: #800000;">'</span><span style="color: #800000;">172.19.26.242:11211</span><span style="color: #800000;">'</span><span style="color: #000000;">,]
}
}</span></pre>
使用Memcache缓存(pylibmc模块)
=: CACHES </span>=<span style="color: #000000;"> {
</span><span style="color: #800000;">'</span><span style="color: #800000;">default</span><span style="color: #800000;">'</span><span style="color: #000000;">: {
</span><span style="color: #800000;">'</span><span style="color: #800000;">BACKEND</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">django.core.cache.backends.memcached.PyLibMCCache</span><span style="color: #800000;">'</span><span style="color: #000000;">,</span><span style="color: #800000;">'</span><span style="color: #800000;">LOCATION</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">/tmp/memcached.sock</span><span style="color: #800000;">'</span><span style="color: #000000;">,}
}
CACHES </span>=<span style="color: #000000;"> {
</span><span style="color: #800000;">'</span><span style="color: #800000;">default</span><span style="color: #800000;">'</span><span style="color: #000000;">: {
</span><span style="color: #800000;">'</span><span style="color: #800000;">BACKEND</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">django.core.cache.backends.memcached.PyLibMCCache</span><span style="color: #800000;">'</span><span style="color: #000000;">,]
}
}</span></pre>
缓存应用
单独视图缓存
<span style="color: #0000ff;">from django.views.decorators.cache <span style="color: #0000ff;">import<span style="color: #000000;"> cache_page
@cache_page(60 * 15<span style="color: #000000;">)
<span style="color: #0000ff;">def<span style="color: #000000;"> my_view(request):
...
方式二:
<span style="color: #0000ff;">from django.views.decorators.cache <span style="color: #0000ff;">import<span style="color: #000000;"> cache_page
urlpatterns </span>=<span style="color: #000000;"> [
url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^foo/([0-9]{1,2})/$</span><span style="color: #800000;">'</span>,cache_page(60 * 15<span style="color: #000000;">)(my_view)),]
即通过装饰器的方式实现,导入模块之后,在需要缓存的函数前加@cache_page(60 15) 6015表示缓存时间是15分钟
局部使用
{</span>% load cache %<span style="color: #000000;">}
b. 使用缓存
{</span>% cache 5000 缓存key %<span style="color: #000000;">}
缓存<a href="/tag/neirong/" target="_blank" class="keywords">内容</a>
{</span>% endcache %}</pre>
全站缓存
内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存
MIDDLEWARE </span>=<span style="color: #000000;"> [
</span><span style="color: #800000;">'</span><span style="color: #800000;">django.middleware.cache.UpdateCacheMiddleware</span><span style="color: #800000;">'</span><span style="color: #000000;">,</span><span style="color: #008000;">#</span><span style="color: #008000;"> 其他中间件...</span>
<span style="color: #800000;">'</span><span style="color: #800000;">django.middleware.cache.FetchFromCacheMiddleware</span><span style="color: #800000;">'</span><span style="color: #000000;">,]
CACHE_MIDDLEWARE_ALIAS </span>= <span style="color: #800000;">""</span><span style="color: #000000;">
CACHE_MIDDLEWARE_SECONDS </span>= <span style="color: #800000;">""</span><span style="color: #000000;">
CACHE_MIDDLEWARE_KEY_PREFIX </span>= <span style="color: #800000;">""</span></pre>
<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0">
<tr>
<td><span style="font-size: 16px;">七、Django中的信号</td>
</tr></table>
简介
Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。
内置信号
方法前,自动触发
post_init 方法后,自动触发
pre_save 自动触发
post_save 自动触发
pre_delete 删除前,自动触发
post_delete 删除后,自动触发
m2m_changed 自动触发
class_prepared 注册的app中modal类,对于每一个类,自动触发
自动触发
post_migrate 自动触发
Request/自动触发
request_finished 自动触发
got_request_exception 自动触发
修改配置文件时,自动触发
template_rendered 自动触发
数据库连接时,自动触发
因为这些信号中并没有注册函数,所以运行时并没有调用触发这些信号
对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数
django.core.signals request_finished
django.core.signals request_started
django.core.signals got_request_exception
<span style="color: #0000ff;">from
django.db.models.signals <span style="color: #0000ff;">import class_prepared <span style="color: #008000;">#<span style="color: #008000;"> 程序启动时,检测已注册的app中的modal类,对于每一个类,自动触发
<span style="color: #0000ff;">from django.db.models.signals <span style="color: #0000ff;">import pre_init,post_init <span style="color: #008000;">#<span style="color: #008000;"> 构造方法前和构造方法后
<span style="color: #0000ff;">from django.db.models.signals <span style="color: #0000ff;">import pre_save,post_save <span style="color: #008000;">#<span style="color: #008000;"> 对象保存前和对象保存后
<span style="color: #0000ff;">from django.db.models.signals <span style="color: #0000ff;">import pre_delete,post_delete <span style="color: #008000;">#<span style="color: #008000;"> 对象
删除前和对象
删除后
<span style="color: #0000ff;">from django.db.models.signals <span style="color: #0000ff;">import m2m_changed <span style="color: #008000;">#<span style="color: #008000;"> 操作第三张表前后
<span style="color: #0000ff;">from django.db.models.signals <span style="color: #0000ff;">import pre_migrate,post_migrate <span style="color: #008000;">#<span style="color: #008000;"> 执行migrate命令前后
<span style="color: #0000ff;">from django.test.signals <span style="color: #0000ff;">import setting_changed <span style="color: #008000;">#<span style="color: #008000;"> 使用test测试修改配置文件时
<span style="color: #0000ff;">from django.test.signals <span style="color: #0000ff;">import template_rendered <span style="color: #008000;">#<span style="color: #008000;"> 使用test测试渲染模板时
<span style="color: #0000ff;">from django.db.backends.signals <span style="color: #0000ff;">import connection_created <span style="color: #008000;">#<span style="color: #008000;"> 创建数据库连接时
<span style="color: #0000ff;">def callback(sender,**<span style="color: #000000;">kwargs):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">xxoo_callback<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">print<span style="color: #000000;">(sender,kwargs)
xxoo.connect(callback)
<span style="color: #008000;">#<span style="color: #008000;"> xxoo指上述导入的内容#示例
from django.core.signals import request_finished
from django.dispatch import receiver
@receiver(request_finished)
def my_callback(sender,**kwargs):
print("Request finished!")<span style="color: #008000;">########################说明####################
注册的函数#如果我们把导入信号以及将注册函数都写到一个单独的文件里,为了在程序启动的时候执行信号中的注册函数,可以在于项目同名的文件中的init文件中导入该文件即可,与使用pyMysqL一样
步骤:
示例:
自动调用,而对于自定义信号则需要开发者在任意位置触发。
=django.dispatch.Signal(providing_args=[,<span style="color: #008000;">#<span style="color: #008000;">注册信号
<span style="color: #0000ff;">def callback(sender,**<span style="color: #000000;">kwargs):
</span><span style="color: #0000ff;">print</span>(<span style="color: #800000;">"</span><span style="color: #800000;">callback</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span><span style="color: #000000;">(sender,kwargs)
pizza_done.connect(callback)
<span style="color: #008000;">#<span style="color: #008000;">触发信号
<span style="color: #0000ff;">from 路径 <span style="color: #0000ff;">import<span style="color: #000000;"> pizza_done
pizza_done.send(sender
=<span style="color: #800000;">'<span style="color: #800000;">seven<span style="color: #800000;">',toppings=123,size=456)