from rest_framework.authentication import BaseAuthentication class TestAuthentication(BaseAuthentication): def authenticate(self, request): """ 用戶認證,若是驗證成功後返回元組: (用戶,用戶Token) :param request: :return: return1:(user,token)表示驗證經過並設置用戶名和Token; return2:AuthenticationFailed異常 return3:None,表示跳過該驗證; 若是跳過了全部認證,默認用戶和Token和使用配置文件進行設置 self._authenticator = None if api_settings.UNAUTHENTICATED_USER: self.user = api_settings.UNAUTHENTICATED_USER() # 默認值爲:匿名用戶 else: self.user = None if api_settings.UNAUTHENTICATED_TOKEN: self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默認值爲:None else: self.auth = None """ ....return ('登陸用戶', '用戶token') def authenticate_header(self, request): """ Return a string to be used as the value of the `WWW-Authenticate` header in a `401 Unauthenticated` response, or `None` if the authentication scheme should return `403 Permission Denied` responses. """ pass
在須要認證的視圖類里加上authentication_classes = [認證組件1類名,認證組件2類名....]html
示例以下:python
seralizers.pydjango
1
2
3
4
5
6
7
|
from
rest_framework
import
serializers
from
app01
import
models
class
PublishSerializers(serializers.ModelSerializer):
class
Meta:
model
=
models.Publish
fields
=
'__all__'
|
auth.pyjson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
from
rest_framework.authentication
import
BaseAuthentication
from
rest_framework
import
exceptions
from
app01
import
models
class
TokenAuth(BaseAuthentication):
def
authenticate(
self
,request):
'''函數名必須叫authenticate'''
# 驗證條件根據需求設置(此示例爲須要有token值)
token
=
request.GET.get(
'token'
)
token_obj
=
models.Token.objects.
filter
(token
=
token).first()
if
not
token_obj:
# 若是驗證失敗,須要跑出AuthenticationFailed錯誤
raise
exceptions.AuthenticationFailed(
"驗證失敗!"
)
else
:
user
=
token_obj.user
# 若是驗證成功,須要返回一個元組,分別是用戶以及驗證類的實例對象,而後內部會賦值給request.user和request.auth
return
user.username,token_obj
|
from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from app01 import models class BlackNameAuth(BaseAuthentication): '''黑名單認證''' def authenticate(self, request): BLACK_NAME_LIST = ['小花', '小翠'] # 經過從url獲取user_id的方式模擬用戶登陸 user_id = request.GET.get('uid') user = models.UserInfo.objects.filter(pk=user_id).first() if not user or user.username in BLACK_NAME_LIST: raise AuthenticationFailed('您沒有登陸或者被關小黑屋啦') else: return user.username,user_id
views.pyapi
1
2
3
4
5
6
7
8
9
10
|
from
rest_framework
import
viewsets
from
app01.auth
import
TokenAuth
class
PublishViewSet(viewsets.ModelViewSet):
# 在這裏配置authentication_classes
# 注意,值爲一個列表,能夠放多個認證組件類名
authentication_classes
=
[TokenAuth]
queryset
=
models.Publish.objects.
all
()
serializer_class
=
serializer.PublishSerializers
|
在setting.py裏配置以下:restful
1
2
3
|
REST_FRAMEWORK
=
{
"DEFAULT_AUTHENTICATION_CLASSES"
: [
"app01.auth.TokenAuth"
,]
}
|
這樣配置以後,每一個視圖類都要通過認證成功以後才能執行下一步,app
若是有某些方法不須要認證,如login函數,則須要在login函數中單獨加入一個配置屬性:dom
1
|
authentication_classes
=
[]
#本身的類裏有的話就調用此類的配置,爲空既什麼都不作
|
class TestPermission(BasePermission): message = "權限驗證失敗" def has_permission(self, request, view): """ 判斷是否有權限訪問當前請求 Return `True` if permission is granted, `False` otherwise. :param request: :param view: :return: True有權限;False無權限 """ if request.user == "管理員": return True # GenericAPIView中get_object時調用 def has_object_permission(self, request, view, obj): """ 視圖繼承GenericAPIView,並在其中使用get_object時獲取對象時,觸發單獨對象權限驗證 Return `True` if permission is granted, `False` otherwise. :param request: :param view: :param obj: :return: True有權限;False無權限 """ if request.user == "管理員": return True
permission.pyide
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from
app01
import
models
class
VipPermission():
def
has_permission(
self
,request,view):
# 通過認證組件以後將用戶名賦值給了request.user
# 這裏能夠直接取到
username
=
request.user
user
=
models.User.objects.
filter
(username
=
username).first()
# 若是用戶的vip值爲1,即爲True,則經過認證,不然return False
if
user.vip:
return
True
else
:
return
False
|
views.py函數
1
2
3
4
5
6
7
8
9
|
from
rest_framework
import
viewsets
from
app01.auth
import
TokenAuth
from
app01.permission
import
VipPermission
class
PublishViewSet(viewsets.ModelViewSet):
authentication_classes
=
[TokenAuth]
permission_classes
=
[VipPermission]
queryset
=
models.Publish.objects.
all
()
serializer_class
=
serializer.PublishSerializers
|
這個時候若是登陸用戶是vip,則會繼續執行下一步,若是是普通用戶,則會返回錯誤信息,以下:
1
|
{
"detail"
:
"You do not have permission to perform this action."
}
|
若是須要自定義錯誤信息,只須要在類裏定義一個message屬性便可,以下:
1
|
message
=
"只有超級用戶才能訪問"
|
1
2
3
4
5
6
|
REST_FRAMEWORK
=
{
# 認證組件
"DEFAULT_AUTHENTICATION_CLASSES"
: [
"app01.auth.TokenAuth"
,],
# 權限組件
"DEFAULT_PERMISSION_CLASSES"
: [
"app01.permission.VipPermission"
,],
}
|
在app01.service.throttles.py中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
from
rest_framework.throttling
import
BaseThrottle
VISIT_RECORD
=
{}
class
VisitThrottle(BaseThrottle):
def
__init__(
self
):
self
.history
=
None
def
allow_request(
self
,request,view):
remote_addr
=
request.META.get(
'REMOTE_ADDR'
)
print
(remote_addr)
import
time
ctime
=
time.time()
if
remote_addr
not
in
VISIT_RECORD:
VISIT_RECORD[remote_addr]
=
[ctime,]
return
True
history
=
VISIT_RECORD.get(remote_addr)
self
.history
=
history
while
history
and
history[
-
1
]<ctime
-
60
:
history.pop()
if
len
(history)<
3
:
history.insert(
0
,ctime)
return
True
else
:
return
False
def
wait(
self
):
import
time
ctime
=
time.time()
return
60
-
(ctime
-
self
.history[
-
1
])
|
在views.py中:
1
2
3
4
5
6
|
from
app01.service.throttles
import
*
class
BookViewSet(generics.ListCreateAPIView):
throttle_classes
=
[VisitThrottle,]
queryset
=
Book.objects.
all
()
serializer_class
=
BookSerializers
|
1
2
3
4
5
|
REST_FRAMEWORK
=
{
"DEFAULT_AUTHENTICATION_CLASSES"
:[
"app01.service.auth.Authentication"
,],
"DEFAULT_PERMISSION_CLASSES"
:[
"app01.service.permissions.SVIPPermission"
,],
"DEFAULT_THROTTLE_CLASSES"
:[
"app01.service.throttles.VisitThrottle"
,]
}
|
在app01.service.throttles.py修改成:
1
2
3
4
5
6
|
class
VisitThrottle(SimpleRateThrottle):
scope
=
"visit_rate"
def
get_cache_key(
self
, request, view):
return
self
.get_ident(request)
|
settings.py設置:
1
2
3
4
5
6
7
8
|
REST_FRAMEWORK
=
{
"DEFAULT_AUTHENTICATION_CLASSES"
:[
"app01.service.auth.Authentication"
,],
"DEFAULT_PERMISSION_CLASSES"
:[
"app01.service.permissions.SVIPPermission"
,],
"DEFAULT_THROTTLE_CLASSES"
:[
"app01.service.throttles.VisitThrottle"
,],
"DEFAULT_THROTTLE_RATES"
:{
"visit_rate"
:
"5/m"
, # 1分鐘5次,同理,5/s,5/h,5/d,表示秒/時/日
}
}
|
views.py上可重寫throttled方法
#首頁支持匿名訪問, #無須要登陸就能夠訪問 class IndexView(APIView): authentication_classes = [MyAuthentcate,] #認證判斷他是否是匿名用戶 permission_classes = [] #通常主頁就不須要權限驗證了 throttle_classes = [AnonThrottle,UserThrottle,] #對匿名用戶和普通用戶的訪問限制 def get(self,request): # self.dispatch return Response('訪問首頁') def throttled(self, request, wait): '''可定製方法設置中文錯誤''' # raise exceptions.Throttled(wait) class MyThrottle(exceptions.Throttled): default_detail = '請求被限制' extra_detail_singular = 'Expected available in {wait} second.' extra_detail_plural = 'Expected available in {wait} seconds.' default_code = '還須要再等{wait}秒' raise MyThrottle(wait) #需登陸就能夠訪問 class ManageView(APIView): authentication_classes = [MyAuthentcate, ] # 認證判斷他是否是匿名用戶 permission_classes = [MyPermission,] # 通常主頁就不須要權限驗證了 throttle_classes = [AnonThrottle, UserThrottle, ] # 對匿名用戶和普通用戶的訪問限制 def get(self, request): # self.dispatch return Response('管理人員訪問頁面') def throttled(self, request, wait): '''可定製方法設置中文錯誤''' # raise exceptions.Throttled(wait) class MyThrottle(exceptions.Throttled): default_detail = '請求被限制' extra_detail_singular = 'Expected available in {wait} second.' extra_detail_plural = 'Expected available in {wait} seconds.' default_code = '還須要再等{wait}秒' raise MyThrottle(wait)
若是有某些方法不須要頻次,如xxx函數,則須要在xxx函數中單獨加入一個配置屬性:
1
|
throttle_classes
=
[]
|
from django.contrib import admin from django.urls import path,re_path,include urlpatterns = [ re_path("testrestfulframework/",include("testrestfulframework.urls")), ] ################# testrestfulframework.urls ############### from django.urls import path,re_path,include from testrestfulframework import views urlpatterns = [ re_path(r"login/$",views.LoginViewSet.as_view()), re_path(r"books/$",views.BookViewSet.as_view()), re_path(r"books/(?P<pk>\d+)$",views.BookDetailViewSet.as_view()), ]
from django.db import models class Book(models.Model): title=models.CharField(max_length=32) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish",on_delete=models.CASCADE) authors=models.ManyToManyField("Author") def __str__(self): return self.title class Publish(models.Model): name=models.CharField(max_length=32) email=models.EmailField() def __str__(self): return self.name class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.name class User(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=64) class Token(models.Model): token = models.CharField(max_length=128) user = models.ForeignKey(to=User,on_delete=models.CASCADE)
# -*- coding:utf-8 -*- from rest_framework.authentication import BaseAuthentication from rest_framework import exceptions from testrestfulframework import models class TokenAuth(BaseAuthentication): def authenticate(self, request): '''函數名必須叫authenticate''' # 驗證條件根據需求設置(此示例爲須要有token值) token = request.GET.get('token') print(request.data) print(request.GET) token_obj = models.Token.objects.filter(token=token).first() if not token_obj: # 若是驗證失敗,須要跑出AuthenticationFailed錯誤 raise exceptions.AuthenticationFailed("驗證失敗!") else: user = token_obj.user # 若是驗證成功,須要返回一個元組,分別是用戶以及驗證類的實例對象,而後內部會賦值給request.user和request.auth return user.username, token_obj
# -*- coding:utf-8 -*- import hashlib, time def get_random_str(user): ctime = str(time.time()) md5 = hashlib.md5(bytes(user, encoding="utf8")) md5.update(bytes(ctime, encoding="utf8")) return md5.hexdigest()
# -*- coding:utf-8 -*- from rest_framework import serializers from testrestfulframework import models class BookSerializers(serializers.ModelSerializer): # publish = serializers.HyperlinkedIdentityField( # view_name='publish_detail', # lookup_field="publish_id", # lookup_url_kwarg="pk") class Meta: model = models.Book fields = "__all__" # depth=1 class PublshSerializers(serializers.ModelSerializer): class Meta: model = models.Publish fields = "__all__" # depth = 1 class AuthorSerializers(serializers.ModelSerializer): class Meta: model = models.Author fields = "__all__" # depth = 1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/testrestfulframework/login/" method="POST"> {% csrf_token %} <div>用戶名:<input type="text" name="username"></div> <div>密碼:<input type="password" name="password"></div> <input type="submit" value="登陸"> </form> </body> </html>
from django.shortcuts import HttpResponse
from rest_framework import mixins
from rest_framework import generics
from testrestfulframework import models
from testrestfulframework import serializers
from testrestfulframework.service.auth import TokenAuth
from testrestfulframework.service import random_token
from rest_framework.views import APIView
from django.http import JsonResponse
from django.shortcuts import render
class LoginViewSet(APIView):
# authentication_classes = [TokenAuth, ]
def get(self,request):
return render(request,"login.html")
def post(self, request, *args, **kwargs):
res = {"code": 1000, "msg": None}
try:
username = request._request.POST.get("username")
password = request._request.POST.get("password")
user_obj = models.User.objects.filter(username=username, password=password).first()
print(username, password, user_obj)
if not user_obj:
res["code"] = 1001
res["msg"] = "用戶名或者密碼錯誤"
else:
token = random_token.get_random_str(username)
models.Token.objects.update_or_create(user=user_obj, defaults={"token": token})
res["token"] = token
except Exception as e:
res["code"] = 1002
res["msg"] = e
import json
print(res)
# return HttpResponse(json.dumps(res))
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
class BookViewSet(generics.ListCreateAPIView):
authentication_classes = [TokenAuth,]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView):
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
第一步:登陸
第二步,手動提取token,並以get方式訪問目標內容。
注意:這裏是手動,實際上徹底能夠在views.py經過url處理redirect到目標url,此處不作這操做。
不帶token
帶token
不作驗證的url可直接訪問
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["testrestfulframework.service.auth.TokenAuth",]
}
from django.shortcuts import HttpResponse
from rest_framework import mixins
from rest_framework import generics
from testrestfulframework import models
from testrestfulframework import serializers
from testrestfulframework.service.auth import TokenAuth
from testrestfulframework.service import random_token
from rest_framework.views import APIView
from django.http import JsonResponse
from django.shortcuts import render
class LoginViewSet(APIView):
# authentication_classes = [TokenAuth, ]
def get(self,request):
return render(request,"login.html")
def post(self, request, *args, **kwargs):
res = {"code": 1000, "msg": None}
try:
username = request._request.POST.get("username")
password = request._request.POST.get("password")
user_obj = models.User.objects.filter(username=username, password=password).first()
print(username, password, user_obj)
if not user_obj:
res["code"] = 1001
res["msg"] = "用戶名或者密碼錯誤"
else:
token = random_token.get_random_str(username)
models.Token.objects.update_or_create(user=user_obj, defaults={"token": token})
res["token"] = token
except Exception as e:
res["code"] = 1002
res["msg"] = e
import json
print(res)
# return HttpResponse(json.dumps(res))
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
class BookViewSet(generics.ListCreateAPIView):
# authentication_classes = [TokenAuth,]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView):
authentication_classes = []
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
驗證結果同上,略。
url.py、serializers.py、models.py均與上例一致。
from rest_framework.permissions import BasePermission class SVIPPermission(BasePermission): message = '沒有訪問權限,請充值超級會員' def has_permission(self, request,view): # auth認證裏面找到user對象的type字段值 role = request.auth.user.role if role == 3: return True else: return False def has_object_permission(self, request,view,obj): # 若是是單個單個條目的detail,須要has_object_permission,此處,obj是該條目 # 可作進一步處理 print(obj) # b001 print(type(obj)) # <class 'testrestfulframework.models.Book'> return True
from django.shortcuts import HttpResponse
from rest_framework import mixins
from rest_framework import generics
from testrestfulframework import models
from testrestfulframework import serializers
from testrestfulframework.service.auth import TokenAuth
from testrestfulframework.service.permissions import SVIPPermission
from testrestfulframework.service import random_token
from rest_framework.views import APIView
from django.http import JsonResponse
from django.shortcuts import render
class LoginViewSet(APIView):
# authentication_classes = [TokenAuth, ]
def get(self,request):
return render(request,"login.html")
def post(self, request, *args, **kwargs):
res = {"code": 1000, "msg": None}
try:
username = request._request.POST.get("username")
password = request._request.POST.get("password")
user_obj = models.User.objects.filter(username=username, password=password).first()
print(username, password, user_obj)
if not user_obj:
res["code"] = 1001
res["msg"] = "用戶名或者密碼錯誤"
else:
token = random_token.get_random_str(username)
models.Token.objects.update_or_create(user=user_obj, defaults={"token": token})
res["token"] = token
res["user"] = user_obj.username
except Exception as e:
res["code"] = 1002
res["msg"] = e
import json
# return HttpResponse(json.dumps(res))
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
class BookViewSet(generics.ListCreateAPIView):
authentication_classes = (TokenAuth,)
permission_classes = (SVIPPermission,)
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView):
authentication_classes = (TokenAuth,)
permission_classes = (SVIPPermission,)
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
REST_FRAMEWORK = {
# "DEFAULT_AUTHENTICATION_CLASSES": ("testrestfulframework.service.auth.TokenAuth",),
'DEFAULT_PERMISSION_CLASSES': ('testrestfulframework.service.permissions.SVIPPermission',)
}
from django.shortcuts import HttpResponse
from rest_framework import mixins
from rest_framework import generics
from testrestfulframework import models
from testrestfulframework import serializers
from testrestfulframework.service.auth import TokenAuth
from testrestfulframework.service.permissions import SVIPPermission
from testrestfulframework.service import random_token
from rest_framework.views import APIView
from django.http import JsonResponse
from django.shortcuts import render
class LoginViewSet(APIView):
# authentication_classes = [TokenAuth, ]
def get(self,request):
return render(request,"login.html")
def post(self, request, *args, **kwargs):
res = {"code": 1000, "msg": None}
try:
username = request._request.POST.get("username")
password = request._request.POST.get("password")
user_obj = models.User.objects.filter(username=username, password=password).first()
print(username, password, user_obj)
if not user_obj:
res["code"] = 1001
res["msg"] = "用戶名或者密碼錯誤"
else:
token = random_token.get_random_str(username)
models.Token.objects.update_or_create(user=user_obj, defaults={"token": token})
res["token"] = token
res["user"] = user_obj.username
except Exception as e:
res["code"] = 1002
res["msg"] = e
import json
# return HttpResponse(json.dumps(res))
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
class BookViewSet(generics.ListCreateAPIView):
authentication_classes = (TokenAuth,)
# permission_classes = (SVIPPermission,)
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView):
authentication_classes = (TokenAuth,)
# permission_classes = (SVIPPermission,)
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
結果同上,略。
# -*- coding:utf-8 -*- from rest_framework.throttling import BaseThrottle VISIT_RECORD = {} class VisitThrottle(BaseThrottle): def __init__(self): self.history = None def allow_request(self, request, view): remote_addr = request.META.get('REMOTE_ADDR') print(remote_addr) import time ctime = time.time() if remote_addr not in VISIT_RECORD: VISIT_RECORD[remote_addr] = [ctime, ] # 這裏只針對源ip作限制,還能夠經過源ip和目標url進行限制,根據本身的設計進行限制。 return True history = VISIT_RECORD.get(remote_addr) self.history = history while history and history[-1] < ctime - 60: # 一分鐘以上的訪問,能夠從history去除,爲history騰出空間 history.pop() if len(history) < 3: # history空間爲3, history.insert(0, ctime) return True else: return False def wait(self): """ 會返回一個這樣的信息:{"detail":"Request was throttled. Expected available in xxx(這裏是60的倒計時) seconds."} """ import time ctime = time.time() return 60 - (ctime - self.history[-1])
from django.shortcuts import HttpResponse
from rest_framework import mixins
from rest_framework import generics
from testrestfulframework import models
from testrestfulframework import serializers
from testrestfulframework.service.auth import TokenAuth
from testrestfulframework.service.permissions import SVIPPermission
from testrestfulframework.service.throttle import VisitThrottle
from testrestfulframework.service import random_token
from rest_framework.views import APIView
from django.http import JsonResponse
from django.shortcuts import render
class LoginViewSet(APIView):
# authentication_classes = [TokenAuth, ]
def get(self,request):
return render(request,"login.html")
def post(self, request, *args, **kwargs):
res = {"code": 1000, "msg": None}
try:
username = request._request.POST.get("username")
password = request._request.POST.get("password")
user_obj = models.User.objects.filter(username=username, password=password).first()
print(username, password, user_obj)
if not user_obj:
res["code"] = 1001
res["msg"] = "用戶名或者密碼錯誤"
else:
token = random_token.get_random_str(username)
models.Token.objects.update_or_create(user=user_obj, defaults={"token": token})
res["token"] = token
res["user"] = user_obj.username
except Exception as e:
res["code"] = 1002
res["msg"] = e
import json
# return HttpResponse(json.dumps(res))
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
class BookViewSet(generics.ListCreateAPIView):
# authentication_classes = (TokenAuth,)
# permission_classes = (SVIPPermission,)
throttle_classes = [VisitThrottle]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView):
# authentication_classes = (TokenAuth,)
# permission_classes = (SVIPPermission,)
throttle_classes = [VisitThrottle]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
import requests
import gevent
from gevent import monkey;monkey.patch_all()
url = "http://127.0.0.1:8000/testrestfulframework/books/"
url = "http://127.0.0.1:8000/testrestfulframework/books/2"
def func(url):
res = requests.request(method="GET",url=url)
print(res.text)
return res.text
gevent.joinall([gevent.spawn(func,url=url) for i in range(10)])
REST_FRAMEWORK = {
# "DEFAULT_AUTHENTICATION_CLASSES": ("testrestfulframework.service.auth.TokenAuth",),
# 'DEFAULT_PERMISSION_CLASSES': ('testrestfulframework.service.permissions.SVIPPermission',),
"DEFAULT_THROTTLE_CLASSES":("testrestfulframework.service.throttle.VisitThrottle",)
}
from django.shortcuts import HttpResponse
from rest_framework import mixins
from rest_framework import generics
from testrestfulframework import models
from testrestfulframework import serializers
from testrestfulframework.service.auth import TokenAuth
from testrestfulframework.service.permissions import SVIPPermission
from testrestfulframework.service.throttle import VisitThrottle
from testrestfulframework.service import random_token
from rest_framework.views import APIView
from django.http import JsonResponse
from django.shortcuts import render
class LoginViewSet(APIView):
# authentication_classes = [TokenAuth, ]
def get(self,request):
return render(request,"login.html")
def post(self, request, *args, **kwargs):
res = {"code": 1000, "msg": None}
try:
username = request._request.POST.get("username")
password = request._request.POST.get("password")
user_obj = models.User.objects.filter(username=username, password=password).first()
print(username, password, user_obj)
if not user_obj:
res["code"] = 1001
res["msg"] = "用戶名或者密碼錯誤"
else:
token = random_token.get_random_str(username)
models.Token.objects.update_or_create(user=user_obj, defaults={"token": token})
res["token"] = token
res["user"] = user_obj.username
except Exception as e:
res["code"] = 1002
res["msg"] = e
import json
# return HttpResponse(json.dumps(res))
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
class BookViewSet(generics.ListCreateAPIView):
# authentication_classes = (TokenAuth,)
# permission_classes = (SVIPPermission,)
# throttle_classes = [VisitThrottle]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
class BookDetailViewSet(generics.RetrieveUpdateDestroyAPIView):
# authentication_classes = (TokenAuth,)
# permission_classes = (SVIPPermission,)
throttle_classes = []
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializers
設置了throttle_classes = []的view
views.py同上
REST_FRAMEWORK = {
# "DEFAULT_AUTHENTICATION_CLASSES": ("testrestfulframework.service.auth.TokenAuth",),
# 'DEFAULT_PERMISSION_CLASSES': ('testrestfulframework.service.permissions.SVIPPermission',),
"DEFAULT_THROTTLE_CLASSES":("testrestfulframework.service.throttle.VisitThrottle",),
"DEFAULT_THROTTLE_RATES": {
"visit_rate": "5/m", # 1分鐘5次,同理,5/s,5/h,5/d,表示秒/時/日
}
}
from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope = "visit_rate"
def get_cache_key(self, request, view):
return self.get_ident(request)
http://www.javashuo.com/article/p-bzhgyogi-ee.html