中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

drf-router和authenticate的使用方法

發布時間:2021-07-12 09:20:35 來源:億速云 閱讀:163 作者:chen 欄目:開發技術

這篇文章主要講解了“drf-router和authenticate的使用方法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“drf-router和authenticate的使用方法”吧!

一、路由Routers

在 Rest Framework 中提供了兩個 router , 可以幫助我們快速的實現路由的自動生成。

必須是繼承 ModelViewSet 的視圖類才能自動生成路由

SimpleRouter

使用方法:

urls.py

# 第一步:導入routers模塊
from rest_framework import routers

# 第二步:實例化得到對象
router = routers.SimpleRouter()  

# 第三步:注冊( register('前綴', viewset視圖集, 路由的別名) )
router.register('books', views.BooksViewset)

# 第四步:生成路由加入到原路由中
# 方式一:
urlpatterns = [
    ...
]
urlpatterns += router.urls

# 方式二:
urlpatterns = [
    ...
    url(r'^', include(router.urls))
]


# 形成路由如下
<URLPattern '^books/$' [name='books-list']>
<URLPattern '^books/(?P<pk>[^/.]+)/$' [name='books-detail']>

DefaultRouter

DefaultRouter與SimpleRouter的區別是,DefaultRouter會多附帶一個默認的API根視圖,返回一個包含所有列表視圖的超鏈接響應數據。

# 前兩條和SimpleRouter一樣
<URLPattern '^books/$' [name='books-list']>
<URLPattern '^books/(?P<pk>[^/.]+)/$' [name='books-detail']>

# 效果也和前兩條類似,
# 如:http://127.0.0.1:8000/books.json
<URLPattern '^books\.(?P<format>[a-z0-9]+)/?$' [name='books-list']>
# http://127.0.0.1:8000/books/1.json
<URLPattern '^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='books-detail']>

# 多了個根路由http://127.0.0.1:8000/
<URLPattern '^$' [name='api-root']>, <URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>

action的使用

action是為了給繼承自 ModelViewSet 的視圖類中自定義的函數也添加路由

例如下面這樣:

from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from app01.ser import BooksSerializers
from app01.models import Books


class BooksViewSet(ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BooksSerializers

    # 這種方法不會自動生成,需要用action配置
    def get_num(self, request, pk):
        book = self.get_queryset()[:int(pk)]
        ser = self.get_serializer(book, many=True)
        return Response(ser.data)

使用示例:

action是一個裝飾器,放在被裝飾的函數上方,

method:請求方式

detail:是否帶pk ——>True 表示路徑格式是xxx/<pk>/action方法名/——False 表示路徑格式是xxx/action方法名/

from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
from app01.ser import BooksSerializers
from app01.models import Books


class BooksViewSet(ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BooksSerializers

    @action(methods=['GET', 'POST'], detail=True)
    def get_num(self, request, pk):
        book = self.get_queryset()[:int(pk)]	# 獲取前幾條數據
        ser = self.get_serializer(book, many=True)
        return Response(ser.data)
    
    
# 生成路由如下
http://127.0.0.1:8000/books/2/get_num/
<URLPattern '^books/(?P<pk>[^/.]+)/get_num/$' [name='books-get-num']>

二、認證

認證的寫法

  • 寫一個認證類,繼承 BaseAuthentication,重寫 authenticate, 認證的邏輯寫在里面,認證通過,返回兩個值,一個值給Request對象的user, 認證失敗,拋異常:APIException或者AuthenticationFailed

  • 將認證類添加到需要認證視圖類的authentication_classes = [認證類1]

  • 全局使用,還是局部使用

# 全局使用,在setting.py中配置
REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
}

# 局部使用,在視圖類上寫
authentication_classes=[MyAuthentication]
# 局部禁用
authentication_classes=[]

認證源碼分析

1、APIView重寫as_view方法使之沒有csrf認證——>但還是正常執行 dispatch 方法,但是 dispatch方法被 APIView重寫了——>dispatch 中執行了 self.initial 認證方法——>有認證,權限,頻率

2、現在只是看認證源碼self.perform_authentication(request)

3、但是self.perform_authentication(request)就一句話:request.user,那么就需要去 drf 的 Request 對象中找 user 屬性(方法)

@property
def user(self):
    # 先去判斷當前對象中有沒有'_user'這個屬性,一開始肯定是沒有的,因為用戶是沒有登錄的
    if not hasattr(self, '_user'):
        with wrap_attributeerrors():
            # 沒有用戶,認證出用戶
            self._authenticate()
    # 有用戶,直接返回用戶
    return self._user

4、Request 類中的 user 方法,剛開始來,沒有_user,走 self._authenticate()

5、核心,就是Request類中的 _authenticate(self)

def _authenticate(self):
    
    # 遍歷拿到一個認證器,進行認證
    # self.authenticators 配置的一堆認證類產生的認證類對象組成的 list
    # self.authenticators 就是在視圖類中配置的:authentication_classes = [認證類1,認證類2] 的一個個認證類的對象:
    
    ————>self.authenticators ==》 [認證類1對象,認證類2對象]
    for authenticator in self.authenticators:
        try:
            
            # 認證器調用認證方法authenticate(認證類對象self,request對象)
            """
            def authenticate(self, request):
        		return (self.force_user, self.force_token)
            """
            # 返回值:登錄的用戶與認證的信息組成的 tuple
            # 并且該方法被try包裹,就代表該方法會拋異常,拋異常就代表認證失敗
            user_auth_tuple = authenticator.authenticate(self) # self是request對象
        except exceptions.APIException:
            self._not_authenticated()
            raise
		
        # 返回值的處理
        if user_auth_tuple is not None:
            self._authenticator = authenticator
            # 如果有返回值,就將 "登錄用戶" 與 "登錄認證" 分別保存到 request.user / request.auth
            self.user, self.auth = user_auth_tuple
            return
	# 如果返回值user_auth_tuple為空,代表認證通過,但是沒有 "登錄用戶" 與 "登錄認證信息",代表游客
    self._not_authenticated()

認證組件的使用

1、寫一個認證類,繼承 BaseAuthentication,重寫 authenticate

# app01_auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01.models import UserToken


class TokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 認證邏輯,如果認證通過,返回兩個值
        # 如果認證失敗,拋出AuthenticationFailed異常
        token = request.data.get('token')
        if token:
            user_token = UserToken.objects.filter(token=token).first()

            # 認證通過
            if user_token:
                return UserToken.user, token
            else:
                raise AuthenticationFailed('認證失敗')
        else:
            raise AuthenticationFailed('請求地址中需要帶token')

2、將認證類添加到需要認證視圖類的authentication_classes = [認證類1]

# views.py
from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from rest_framework.response import Response
from app01.models import Books, UserInfo, UserToken
from app01.ser import BooksSerializer
from app01.app01_auth import TokenAuthentication
import uuid


# 查看Books需要經過認證才能查看
class BooksView(ModelViewSet):
    authentication_classes = [TokenAuthentication]

    queryset = Books.objects.all()
    serializer_class = BooksSerializer


# 登錄視圖,登錄后獲得token,后續用token認證
class LoginView(APIView):

    def post(self, request):
        response_msg = {'status': 200, 'msg': ''}
        username = request.data.get('username')
        password = request.data.get('password')
        user_obj = UserInfo.objects.filter(username=username, password=password).first()

        if user_obj:
            # 登錄成功生成一個隨機字符串
            token = uuid.uuid4()
            
            # 存到UserToken表中,update_or_create有就更新,沒有就新增
            UserToken.objects.update_or_create(defaults={'token': token}, user=user_obj)
            response_msg['msg'] = '登錄成功'
            response_msg['token'] = token
        else:
            response_msg['msg'] = '賬戶或密碼錯誤'
            response_msg['status'] = 204
        return Response(response_msg)

感謝各位的閱讀,以上就是“drf-router和authenticate的使用方法”的內容了,經過本文的學習后,相信大家對drf-router和authenticate的使用方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

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

AI

龙州县| 凌云县| 澎湖县| 泗洪县| 石渠县| 丰顺县| 呼玛县| 和顺县| 泽普县| 平乐县| 屏东县| 西峡县| 卢龙县| 项城市| 威远县| 乡宁县| 宜丰县| 镇宁| 禹州市| 东乡族自治县| 灌云县| 井冈山市| 松滋市| 永善县| 隆德县| 新疆| 明溪县| 濮阳市| 安溪县| 东丽区| 凉城县| 两当县| 曲松县| 淳安县| 贵德县| 内江市| 图们市| 勃利县| 潼南县| 涟水县| 万山特区|