Django rest framework工具包简单用法示例
本文实例讲述了Djangorestframework工具包简单用法。分享给大家供大家参考,具体如下:
Djangorestframework工具包做API非常方便。
下面简单说一下几个功能的实现方法。
实现功能为,匿名用户访问首页一分钟能访问3次,登录用户一分钟访问6次,只有登录用户才能访问order页面。
第一步,注册app
INSTALLED_APPS=[ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app.apps.AppConfig', 'rest_framework',#注册 ]
settings文件注册app
第二步,定义URL,注意url路径最好使用名词。我们这里注册三个视图函数的url,实现验证,首页和定单页面。
fromdjango.conf.urlsimporturl fromdjango.contribimportadmin fromappimportviews urlpatterns=[ url(r'^admin/',admin.site.urls), url(r'^auth/',views.AuthView.as_view()),#验证 url(r'^index/',views.IndexView.as_view()),#首页 url(r'^order/',views.OrderView.as_view()),#定单 ]
url文件设置路由
第三步,auth视图函数
fromrest_framework.viewsimportAPIView
fromrest_framework.requestimportRequest
fromdjango.httpimportJsonResponse,HttpResponse
fromapp.utils.commonsimportgen_token
fromapp.utils.authimportLuffyAuthentication
fromapp.utils.throttleimportLuffyAnonRateThrottle,LuffyUserRateThrottle
fromapp.utils.permissionimportLuffyPermission
from.importmodels
classAuthView(APIView):
"""
认证相关视图
由于继承了APIView,所以csrf就没有了,具体的源代码只是有一个装饰器,
加上了csrf_exempt装饰器,屏蔽了csrf
写法是在return的时候csrf_exempt(view)和@使用装饰器效果是一样的,这种写法还可以写在url路由中。
"""
defpost(self,request,*args,**kwargs):
"""
用户登录功能
:paramrequest:
:paramargs:
:paramkwargs:
:return:
"""
ret={'code':1000,'msg':None}
#默认要返回的信息
user=request.data.get('username')
#这里的request已经不是原来的request了
pwd=request.data.get('password')
user_obj=models.UserInfo.objects.filter(user=user,pwd=pwd).first()
ifuser_obj:
tk=gen_token(user)#返回一个哈希过得字符串
#进行token验证
models.Token.objects.update_or_create(user=user_obj,defaults={'token':tk})
#数据库存入一个token信息
ret['code']=1001
ret['token']=tk
else:
ret['msg']="用户名或密码错误"
returnJsonResponse(ret)
上面的代码主要是实现了一个验证的功能,通过gen_token函数来验证,并存入数据库信息。
gen_token单独写到一个utils目录下的auth.py文件中。代码如下:
defgen_token(username):
importtime
importhashlib
ctime=str(time.time())
hash=hashlib.md5(username.encode('utf-8'))
hash.update(ctime.encode('utf-8'))
returnhash.hexdigest()
通过时间和哈希等生成一个不重复的字符串。
第四步,index视图函数
classIndexView(APIView):
"""
用户认证
http://127.0.0.1:8001/v1/index/?tk=sdfasdfasdfasdfasdfasdf
获取用户传入的Token
首页限制:request.user
匿名:5/m
用户:10/m
"""
authentication_classes=[LuffyAuthentication,]
#认证成功返回一个用户名,一个对象,不成功就是None
throttle_classes=[LuffyAnonRateThrottle,LuffyUserRateThrottle]
#访问次数限制,如果合格都为True
defget(self,request,*args,**kwargs):
returnHttpResponse('首页')
同样,将LuffyAuthentication,LuffyAnonRateThrottle,LuffyUserRateThrottle写到了utils目录下。代码如下:
auth.py:
fromrest_framework.authenticationimportBaseAuthentication
fromrest_frameworkimportexceptions
fromappimportmodels
classLuffyAuthentication(BaseAuthentication):
defauthenticate(self,request):
tk=request.query_params.get('tk')
ifnottk:
return(None,None)
#raiseexceptions.AuthenticationFailed('认证失败')
token_obj=models.Token.objects.filter(token=tk).first()
ifnottoken_obj:
return(None,None)
return(token_obj.user,token_obj)
验证是否为登录用户,如果之前没有登陆过,则将token信息存到数据库
throttle.py:
fromrest_framework.throttlingimportBaseThrottle,SimpleRateThrottle
classLuffyAnonRateThrottle(SimpleRateThrottle):
scope="luffy_anon"
defallow_request(self,request,view):
"""
Return`True`iftherequestshouldbeallowed,`False`otherwise.
"""
ifrequest.user:
returnTrue
#获取当前访问用户的唯一标识
self.key=self.get_cache_key(request,view)
#根据当前用户的唯一标识,获取所有访问记录
#[1511312683.7824545,1511312682.7824545,1511312681.7824545]
self.history=self.cache.get(self.key,[])
#获取当前时间
self.now=self.timer()
#Dropanyrequestsfromthehistorywhichhavenowpassedthe
#throttleduration
whileself.historyandself.history[-1]<=self.now-self.duration:
self.history.pop()
iflen(self.history)>=self.num_requests:#判断访问次数是否大于限制次数
returnself.throttle_failure()
returnself.throttle_success()#返回True
defget_cache_key(self,request,view):
return'throttle_%(scope)s_%(ident)s'%{
'scope':self.scope,
'ident':self.get_ident(request),
#判断是否为代理等等
}
classLuffyUserRateThrottle(SimpleRateThrottle):
scope="luffy_user"
defallow_request(self,request,view):
"""
Return`True`iftherequestshouldbeallowed,`False`otherwise.
"""
ifnotrequest.user:#判断登录直接返回True
returnTrue
#获取当前访问用户的唯一标识
#用户对所有页面
#self.key=request.user.user
self.key=request.user.user+view.__class__.__name__
#用户对单页面的访问限制
#根据当前用户的唯一标识,获取所有访问记录
#[1511312683.7824545,1511312682.7824545,1511312681.7824545]
self.history=self.cache.get(self.key,[])
#获取当前时间
self.now=self.timer()
#Dropanyrequestsfromthehistorywhichhavenowpassedthe
#throttleduration
whileself.historyandself.history[-1]<=self.now-self.duration:
self.history.pop()
iflen(self.history)>=self.num_requests:#访问次数的限制
returnself.throttle_failure()
returnself.throttle_success()#返回True
限制匿名用户和登录用户的访问次数,需要从settings中的配置拿去配置信息。
permission.py
fromrest_framework.permissionsimportBasePermission classLuffyPermission(BasePermission): defhas_permission(self,request,view): """ Return`True`ifpermissionisgranted,`False`otherwise. """ ifrequest.user: returnTrue returnFalse
权限控制
第五步,order视图函数
classOrderView(APIView):
"""
订单页面:只有登录成功后才能访问
-认证(匿名和用户)
-权限(用户)
-限制()
"""
authentication_classes=[LuffyAuthentication,]
permission_classes=[LuffyPermission,]#登录就返回True
throttle_classes=[LuffyAnonRateThrottle,LuffyUserRateThrottle]
defget(self,request,*args,**kwargs):
returnHttpResponse('订单')
第六步,settings配置
REST_FRAMEWORK={
'UNAUTHENTICATED_USER':None,
'UNAUTHENTICATED_TOKEN':None,
"DEFAULT_THROTTLE_RATES":{
'luffy_anon':'3/m',#匿名用户一分钟访问3次
'luffy_user':'6/m'#登录用户一分钟访问6次
},
}
最后,实现功能为,匿名用户访问首页一分钟能访问3次,登录用户一分钟访问6次,只有登录用户才能访问order页面。
学习Djangorestframework需要随时查看源代码,判断源代码的逻辑思路来自定义自己的功能,如此学习效率极高。
希望本文所述对大家基于Django框架的Python程序设计有所帮助。