rest_framework 视图/路由/渲染器/认证授权/节流
視圖
?1. 整理
class View: django view
class APIView(View):? ? rest框架基礎view,適合直接繼承,重寫get post方法
class GenericAPIView(views.APIView): 對ApiView進一步包裝,方法重寫,不適合直接繼承使用,適合配合mixin
功能擴展 ,以下各實現部分 get post delete put patch 方法,但未重寫asview,需要進一步改寫,奇怪的類。。。
?
ViewSetMixin 重寫了as_view方法,可以把httpmethod的?get post delete put patch轉化為不同方法。
GenericViewSet? 可以自定制,適合直接繼承,轉化httpmethod的?get post delete put patch轉化為自定制方法。也可已結合部分XXModelViewSet
ModelViewSet 高度整合, 適合直接繼承,用于增刪改查可以把httpmethod的?get post delete put patch轉化為list,create,destroy,update,pratial_update
?
總結
?
2. modelviewset
views.py
class TestViewSet(ModelViewSet):queryset = UserInfo.objects.all()serializer_class = UserInfoSerializerpagination_class=MyPagination View Codeurls.py
path('testviewset/',app01views.TestViewSet.as_view({'get':'list','post':'create'})),re_path('testviewset/(?P<pk>\d+)/',app01views.TestViewSet.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})), View Code?由于Response返回形式 ,加入?format=json返回json或者在url改寫
# http://127.0.0.1:8000/testviewset/jsonre_path('testviewset/(?P<format>\w+)',app01views.TestViewSet.as_view({'get':'list','post':'create'})), View Code?
自動路由
?當實現了modelviewset時的的自動路由
from rest_framework import routersrouter=routers.DefaultRouter() router.register(r'testrouter',app01views.TestViewSet)urlpatterns = [path('',include(router.urls)), ]#訪問http://127.0.0.1:8000/testrouter/ View Code或
from rest_framework import routersrouter=routers.DefaultRouter() router.register(r'',app01views.TestViewSet)urlpatterns = [path('testrouter/',include(router.urls)), ] View Code?
渲染器
from rest_framework.renderers import AdminRenderer,JSONRenderer,BrowsableAPIRenderer class TestViewSet(ModelViewSet):renderer_classes = [JSONRenderer,BrowsableAPIRenderer]queryset = UserInfo.objects.all()serializer_class = UserInfoSerializerpagination_class=MyPagination View Code?
認證授權
參考http://www.cnblogs.com/wupeiqi/articles/7805382.html
from rest_framework.authentication import BaseAuthentication from rest_framework.permissions import BasePermissionclass TestAuthentication(BaseAuthentication):def authenticate(self, request):"""用戶認證,如果驗證成功后返回元組: (用戶,用戶Token):param request: :return: None,表示跳過該驗證;如果跳過了所有認證,默認用戶和Token和使用配置文件進行設置self._authenticator = Noneif api_settings.UNAUTHENTICATED_USER:self.user = api_settings.UNAUTHENTICATED_USER() # 默認值為:匿名用戶else:self.user = Noneif api_settings.UNAUTHENTICATED_TOKEN:self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默認值為:Noneelse:self.auth = None(user,token)表示驗證通過并設置用戶名和Token;AuthenticationFailed異常"""val = request.query_params.get('token')if val not in token_list:raise exceptions.AuthenticationFailed("用戶認證失敗")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 theauthentication scheme should return `403 Permission Denied` responses."""passclass 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 Trueclass TestView(APIView):# 認證的動作是由request.user觸發authentication_classes = [TestAuthentication, ]# 權限# 循環執行所有的權限permission_classes = [TestPermission, ]def get(self, request, *args, **kwargs): View Code全局
REST_FRAMEWORK = {'UNAUTHENTICATED_USER': None,'UNAUTHENTICATED_TOKEN': None,"DEFAULT_AUTHENTICATION_CLASSES": ["web.utils.TestAuthentication",],"DEFAULT_PERMISSION_CLASSES": ["web.utils.TestPermission",], } View Code?節流
?
import time from rest_framework.views import APIView from rest_framework.response import Responsefrom rest_framework import exceptions from rest_framework.throttling import BaseThrottle from rest_framework.settings import api_settings# 保存訪問記錄 RECORD = {'用戶IP': [12312139, 12312135, 12312133, ] }class TestThrottle(BaseThrottle):ctime = time.timedef get_ident(self, request):"""根據用戶IP和代理IP,當做請求者的唯一IPIdentify the machine making the request by parsing HTTP_X_FORWARDED_FORif present and number of proxies is > 0. If not use all ofHTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR."""xff = request.META.get('HTTP_X_FORWARDED_FOR')remote_addr = request.META.get('REMOTE_ADDR')num_proxies = api_settings.NUM_PROXIESif num_proxies is not None:if num_proxies == 0 or xff is None:return remote_addraddrs = xff.split(',')client_addr = addrs[-min(num_proxies, len(addrs))]return client_addr.strip()return ''.join(xff.split()) if xff else remote_addrdef allow_request(self, request, view):"""是否仍然在允許范圍內Return `True` if the request should be allowed, `False` otherwise.:param request: :param view: :return: True,表示可以通過;False表示已超過限制,不允許訪問"""# 獲取用戶唯一標識(如:IP)# 允許一分鐘訪問10次num_request = 10time_request = 60now = self.ctime()ident = self.get_ident(request)self.ident = identif ident not in RECORD:RECORD[ident] = [now, ]return Truehistory = RECORD[ident]while history and history[-1] <= now - time_request:history.pop()if len(history) < num_request:history.insert(0, now)return Truedef wait(self):"""多少秒后可以允許繼續訪問Optionally, return a recommended number of seconds to wait beforethe next request."""last_time = RECORD[self.ident][0]now = self.ctime()return int(60 + last_time - now)class TestView(APIView):throttle_classes = [TestThrottle, ]def get(self, request, *args, **kwargs):# self.dispatchprint(request.user)print(request.auth)return Response('GET請求,響應內容')def post(self, request, *args, **kwargs):return Response('POST請求,響應內容')def put(self, request, *args, **kwargs):return Response('PUT請求,響應內容')def throttled(self, request, wait):"""訪問次數被限制時,定制錯誤信息"""class Throttled(exceptions.Throttled):default_detail = '請求被限制.'extra_detail_singular = '請 {wait} 秒之后再重試.'extra_detail_plural = '請 {wait} 秒之后再重試.'raise Throttled(wait) View Code?
轉載于:https://www.cnblogs.com/infaaf/p/9580685.html
總結
以上是生活随笔為你收集整理的rest_framework 视图/路由/渲染器/认证授权/节流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2018及以后的热门网络技巧
- 下一篇: android社会化分享