91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Django REST_framework框架 03

發布時間:2020-07-12 03:52:50 來源:網絡 閱讀:419 作者:jedi911 欄目:編程語言

權限組件

源碼

權限組件的源碼執行過程和之前的認證組件是相同的,如下:

self.check_permissions(request)
def check_permissions(self, request):
    """
    Check if the request should be permitted.
    Raises an appropriate exception if the request is not permitted.
    """
    for permission in self.get_permissions():
        if not permission.has_permission(request, self):
            self.permission_denied(
                request, message=getattr(permission, 'message', None)
            )

思考:如果要做權限認證,我們首先要知道當前登錄的用戶是誰,那么我們如何知道呢?
首先rest_framework中的三個組件是按順序執行的:

#認證組件
self.perform_authentication(request)
#權限組件
self.check_permissions(request)
#頻率組件
self.check_throttles(request)

在第一個執行的認證組件源碼中有這樣一段代碼

self.user, self.auth = user_auth_tuple

這個user_auth_tuple恰巧就是我們自定義認證視圖時返回的那個元祖

class TokenAuth(BaseAuthentication):
def authenticate(self, request):
......
return token_obj.user, token_obj.token #需要返回一個元組

因此此時的self.user=token_obj.user,self.auth=token_obj.token

局部視圖權限

在app01.service.permissions.py中:

from rest_framework.permissions import BasePermission
class SVIPPermission(BasePermission):
    message = "SVIP才能訪問" #沒通過驗證則返回錯誤
    def has_permission(self, request, view): #固定寫法
        if request.user.user_type == 3:
            return True
        return False

在views.py:

class AuthorView(viewsets.ModelViewSet):
    authentication_classes = [TokenAuth,]
    permission_classes = [SVIPPermission,]
    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers

全局視圖權限

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
    "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",]
}

throttle(訪問頻率)組件

源碼

self.check_throttles(request)
def check_throttles(self, request):
    """
    Check if request should be throttled.
    Raises an appropriate exception if the request is throttled.
    """
    for throttle in self.get_throttles():
        if not throttle.allow_request(request, self):
            self.throttled(request, throttle.wait())

局部視圖throttle

在app01.service.throttles.py中:

from rest_framework.throttling import BaseThrottle

class VisitThrottle(BaseThrottle):
    def allow_request(self,request,view):
        if 1:
            return True
        return False

在views.py中:

from app01.service.throttles import *

class BookViewSet(generics.ListCreateAPIView):
    throttle_classes = [VisitThrottle,]
    queryset = Book.objects.all()
    serializer_class = BookSerializers

全局視圖throttle

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
    "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],
    "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",]
}

內置throttle類

https://www.cnblogs.com/yuanchenqi/articles/8719520.html#_label3

解析器

解析器是將接收到的數據轉換為我們所需要的數據類型,是反序列化的過程,例如將前端傳過來的JSON解析為字典,rest_framework可以直接從request.data中取出反序列化后的JSON數據,依賴的就是解析器

局部視圖

from rest_framework.parsers import JSONParser,FormParser
class PublishViewSet(generics.ListCreateAPIView):
    parser_classes = [FormParser,JSONParser] #只寫了兩種解析器,默認有三種
    queryset = Publish.objects.all()
    serializer_class = PublshSerializers
    def post(self, request, *args, **kwargs):
        print("request.data",request.data)
        return self.create(request, *args, **kwargs)

全局視圖

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",
    },
    "DEFAULT_PARSER_CLASSES":['rest_framework.parsers.FormParser',]
}

如果我們自己不設置parser_classes那么就會去父類中找

parser_classes = api_settings.DEFAULT_PARSER_CLASSES

而父類中的默認設置已經包含了常用的三種解析,包括解析JSON數據和urlencoded數據等,因此這里不太需要修改

'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
),

思考:在實際開發過程中,如果我們需要解析一個特殊的數據類型,那么可以自己寫一個解析器(類),然后加到parser_classes = []中,這樣就可以在request.data中直接取出這種特殊數據類型反序列化后的結果了

URLs-路由控制補充知識

進一步封裝url

原有url

我們知道下面兩條url都針對一個視圖類,但每個表這寫兩條url的話就會造成代碼重復,因為不同表的每條url只有視圖類的名字和反向解析的名字有區別而已,這里可以進一步封裝

url(r'^authors/$', views.AuthorView.as_view({"get": "list", "post": "create"}), name="author"),
url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"),
class AuthorView(viewsets.ModelViewSet):

    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers

新url

from rest_framework import routers
from django.conf.urls import include
from app01 import views

router = routers.DefaultRouter()  #實例化一個對象
router.register(r'authors', views.AuthorView)  #注冊,前面寫表名,后面寫視圖類的名字

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url('', include(router.urls)),
]

再訪問就會自動生成四條url

^authors/$ [name='author-list']
^authors\.(?P<format>[a-z0-9]+)/?$ [name='author-list']
^authors/(?P<pk>[^/.]+)/$ [name='author-detail']
^authors/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='author-detail']

分頁組件

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination

分頁器A-簡單分頁

class PNPagination(PageNumberPagination):
    page_size = 2 #默認每頁顯示幾條
    page_query_param = 'page' #url上get請求時的關鍵字,表示第幾頁 ?page=2

    page_size_query_param = 'size' #url關鍵字,臨時設置每頁顯示幾條,與默認區分 ?size=2
    max_page_size = 3 #用于限制page_size_query_param的最大值,即每頁顯示條數最多不能超過這個限制

分頁器B-偏移分頁

class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 3 #默認顯示幾條數據
    limit_query_param = 'limit' #url關鍵字,臨時設置每頁顯示幾條數據
    offset_query_param = 'offset' #url關鍵字,偏移,默認從0開始,與limit可以配合

viewsA:

class BookView(APIView):

    def get(self, request):
        book_list = Book.objects.all()
        # 分頁
        pnp = MyLimitOffsetPagination()
        pager_books = pnp.paginate_queryset(book_list, request, self)

        ret = BookModelSerializers(pager_books, many=True, context={'request': request})

        # 此處的Response來自rest_framework
        return Response(ret.data)

viewsB:

class AuthorView(viewsets.ModelViewSet):

    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers
    pagination_class = MyLimitOffsetPagination #定義分頁器類
返回值
{
    "count": 4, #數據總數
    "next": "http://127.0.0.1:8000/authors/?page=2", #下一頁的url
    "previous": null,
......
}

偏移分頁示例

每頁顯示一條數據的同時,從第一條數據開始向右偏移兩條數據,顯示結果是第三條數據
http://127.0.0.1:8000/books/?limit=1&offset=2
每頁顯示兩條數據的同時,從第一條數據開始向右偏移兩條數據,顯示結果是第三第四條數據
http://127.0.0.1:8000/books/?limit=2&offset=2

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

上高县| 新乡县| 通江县| 太湖县| 宜昌市| 会昌县| 大名县| 镇巴县| 许昌县| 阿图什市| 邵东县| 嘉荫县| 小金县| 木兰县| 获嘉县| 金堂县| 虹口区| 利津县| 荔波县| 布尔津县| 石狮市| 新津县| 蕉岭县| 子洲县| 庆城县| 松潘县| 确山县| 蕲春县| 泰州市| 土默特左旗| 彰化市| 宜宾市| 万宁市| 光泽县| 探索| 茶陵县| 承德县| 澄江县| 长治县| 翁源县| 临夏市|