Django框架之drf
一、認證元件
簡介:
登入認證的限制
認證元件是drf框架給我們提供的認證介面,它能夠在請求進入檢視函式/類前進驗證(例如:認證使用者是否登入),對不符合認證的請求進行攔截並返回校驗失敗的資訊
1、認證元件使用步驟
模組地址:
from rest_framework.authentication import BaseAuthentication
用法簡介:
# 1、建立一個專門用於認證的py檔案,寫一個類繼承BaseAuthentication
# 2、重寫authenticate方法,在方法內驗證token
# 3、如果認證成功,返回兩個值【返回None或兩個值(當前登入的物件和token)】
# 4、認證不透過,拋異常AuthenticationFailed(異常資訊)
# 5、區域性使用和全域性使用
-區域性使用:# 在需要使用認證的檢視類下管理介面
class BookDetailView(ViewSetMixin, RetrieveAPIView):
authentication_classes = [LoginAuth] # 列表,可以新增多個
-全域性使用:# 在django的setting.py檔案種新增配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':['app01.authenticate.LoginAuth']
}
-區域性禁用:# 全域性開啟,區域性禁用
class BookDetailView(ViewSetMixin, RetrieveAPIView):
authentication_classes = []
2、程式碼用法
認證類程式碼:(authentica.py)
class LoginAuth(BaseAuthentication):
# 在這裡實現認證,如果是登入的,繼續往後走返回兩個值,如果不是拋異常
def authenticate(self, request):
# 請求中是否攜帶token,判斷是否登入,放在位址列中
token = request.query_params.get('token', None)
# 判斷前端是否傳入token
if token:
# 去表中查詢token
user_token = UserToken.objects.filter(token=token).first()
# 判斷是否查到token
if user_token:
# 找到了返回兩個值:登入的物件和token
return user_token.user, token
else:
# 沒有登入拋異常
raise AuthenticationFailed('token認證失敗')
else:
raise AuthenticationFailed('token沒傳')
檢視類程式碼
# 查詢所有
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 控制認證的介面(列表,可以在認證的py檔案下編寫多個認證)
authentication_classes = [LoginAuth] # 區域性認證
路由程式碼
from django.urls import path, include
from app01 import views
# 第一步:匯入模組
from rest_framework.routers import SimpleRouter
# 第二步:例項化物件
router = SimpleRouter()
# 第三步:註冊路由
router.register('books', views.BookView, 'books')
urlpatterns = [
path('', include(router.urls))
]
二、許可權元件
簡介:
在我們使用的一些app或者網頁中(愛奇藝,騰訊影片),都會有一些會員介面(需要購買會員才能夠使用或者觀看),許可權元件就是對使用者的這一許可權進行驗證,在請求進入檢視類/函式程式碼前進行校驗,校驗失敗後直接將請求攔截,並返回校驗失敗的資訊
1、許可權元件的使用步驟
模組地址:
from rest_framework.permissions import BasePermission
用法簡介:
# 1、建立一個專門用於編寫許可權元件的py檔案,寫一個許可權類,繼承BasePermission
# 2、重寫has_permission方法(在該方法在中實現許可權認證,在這方法中,request.user就是當前登入使用者)
# 3、如果有許可權,返回True
# 4、沒有許可權,返回False(定製返回的中文: self.message='中文')
# 5、區域性使用和全域性使用
-區域性使用: # 在某個檢視類中設定介面(不會影響別的檢視類)
class BookDetailView(ViewSetMixin, RetrieveAPIView):
permission_classes = [CommonPermission]
-全域性使用: # django的settings.py中配置,影響全域性
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'app01.permissions.CommonPermission',
],
}
-區域性禁用:# 全域性配置區域性禁用
class BookDetailView(ViewSetMixin, RetrieveAPIView):
permission_classes = []
2、程式碼用法
許可權類程式碼(perssion.py)
# 寫許可權類,寫一個類,繼承基類BasePermission,重寫has_permission方法,在方法中實現許可權認證,如果有許可權return True ,如果沒有許可權,返回False
from rest_framework.permissions import BasePermission
class CommonPermission(BasePermission):
def has_permission(self, request, view):
# 實現許可權的控制 ---》知道當前登入使用者是誰?當前登入使用者是 request.user
if request.user.user_type == 1:
return True
else:
# 沒有許可權,向物件中放一個屬性 message
# 如果表模型中,使用了choice,就可以透過 get_欄位名_display() 拿到choice對應的中文
self.message = '您是【%s】,您沒有許可權' % request.user.get_user_type_display()
return False
檢視類程式碼:
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 區域性認證
authentication_classes = [LoginAuth]
# 許可權認證(將編寫的頻率類匯入過來)
permission_classes = [CommentPermission]
三、頻率
簡介:
頻率是指,控制某個介面訪問頻率(次數)
1、頻率元件的使用步驟
模組地址:
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
# BaseThrottle:需要手動編寫的程式碼較多
# SimpleRateThrottle: 需要手動編寫的程式碼較少(用這個)
用法簡介
# 1、建立一個專門用來編寫頻率元件的py檔案,寫一個頻率類,繼承SimpleRateThrottle
# 2、重寫get_cache_key方法,返回什麼,就以什麼做限制----》ip(使用者id做限制)
# 3、配置一個類屬性scope = 'book_5_m'
# 4、在django的配置檔案中編寫頻率次數
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'book_5_m': '5/m', # 一分鐘五次
},
}
# 5、區域性使用和全域性使用
-區域性使用: # 隻影響當前的檢視類
class BookView(ModelViewSet):
throttle_classes = [CommentThrottle]
-全域性配置:影響全域性
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'],
}
-區域性禁用:
class BookView(ModelViewSet):
throttle_classes = [CommentThrottle]
2、程式碼用法
頻率類程式碼(throttle.py)
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
class CommentThrottle(SimpleRateThrottle):
# 建立一個用於控制頻率的變數名(需要傳入配置檔案)
scope = 'book_5_m'
def get_cache_key(self, request, view):
# 返回什麼就以什麼做限制(request.META.get('REMOTE_ADDR')以IP做限制)
return request.META.get('REMOTE_ADDR')
檢視類程式碼
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 頻率元件
throttle_classes = [CommentThrottle]
django配置檔案
REST_FRAMEWORK = {
# 控制訪問頻率
'DEFAULT_THROTTLE_RATES': {
'book_5_m': '5/m', # 一分鐘五次
},
}
四、過濾的多種用法
簡介:
過濾是指在使用查詢的時候,我們可以透過條件來過濾掉不需要的內容(例如:使用淘寶購物時,購買某種物品,過濾掉價格低於100元的商品)
# restful規範中,要求了,請求地址中帶過濾條件
-5個介面中,只有一個介面需要有過濾和排序,查詢所有介面
1、繼承APIView自己寫
class BookView(APIView):
def get(self,request):
# 獲取get請求攜帶的引數
name=request.query_params.get('name')
# 透過filter進行過濾
books = Book.objects.filter(name=name)
2、使用drf的內建過濾(繼承GenericAPIview)
模組地址:
-該方法為模糊查詢
from rest_framework.filters import SearchFilter
程式碼用法:
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 例項化過濾物件
filter_backends = [SearchFilter]
# 指定過濾的欄位(模糊查詢)
search_fields = ['name', 'price']
搜尋方式:
# name或price中只要有關鍵字就會搜出來 (只能用search=xxx的方式)
http://127.0.0.1:8000/api/v1/books/?search=西遊記
3、使用第三方外掛過濾(精準過濾)
第三方外掛:
# 外掛名稱:
django-filter
# 安裝外掛:
pip3.8 install django-filter
模組地址:
from django_filters.rest_framework import DjangoFilterBackend
程式碼用法:
from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializer import BookSerializer
from django_filters.rest_framework import DjangoFilterBackend
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 第三方過濾外掛
filter_backends = [DjangoFilterBackend]
# 查詢的欄位
filterset_fields = ['pk','name', 'price']
搜尋方式:
http://127.0.0.1:8000/api/books/?price=99
http://127.0.0.1:8000/api/books/?price=99&name=吶喊
4、使用過濾元件
4、1.定製過濾元件的使用方式與步驟
模組地址:
from rest_framework.filters import BaseFilterBackend
用法簡介:
# 1、建立一個專門用於過濾的py檔案,寫一個類繼承BaseFilterBackend
# 2、重寫filter_queryset方法,在方法內部進行過濾
# 3、直接返回過濾後的物件
# 4、如果沒有過濾直接返回所有資料
# 5、區域性使用
-區域性使用:
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 在類表內填寫過濾的類
filter_backends = [CommonFilter] # 可以定製多個,從左往右,依次執行
4、2.程式碼用法
過濾類程式碼(filters.py)
from rest_framework.filters import BaseFilterBackend
class CommonFilter(BaseFilterBackend):
# 重寫的類,編寫過濾吧的內容
def filter_queryset(self, request, queryset, view):
# 獲取過濾的條件
filter_comment = request.query_params.get('price_gt', None)
# 判斷前端是否傳入過濾條件
if filter_comment:
# 根據條件進行賽選內容
books_queryset_filter = queryset.filter(price__gt=100)
# 返回過濾後的資料
return books_queryset_filter
return queryset
檢視類程式碼
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 第三方過濾外掛
filter_backends = [CommonFilter]
五、排序
1、用法簡介
用法簡介:
排序需要和自定義過濾繼承同一個父類,需要將排序的物件填入在過濾的列表內,並且放在其他引數的前方
模組地址:
from rest_framework.filters import OrderingFilter
2、程式碼用法
檢視類程式碼
from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializer import BookSerializer
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CommonFilter
from rest_framework.filters import OrderingFilter
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 第三方過濾外掛(OrderingFilter放在其他過濾引數前)
filter_backends = [OrderingFilter, DjangoFilterBackend, CommonFilter]
# 查詢的欄位
filterset_fields = ['id', 'name', 'price']
# 指定排序的欄位(-是降序,預設升序)
ordering_fields = ['price']
搜尋用法
# 預設升序
http://127.0.0.1:8000/api/books/?price_gt=60&ordering=price
# 降序
http://127.0.0.1:8000/api/books/?price_gt=60&ordering=-price
六、分頁
1、用法簡介
- 只有查詢所有介面才能到用到分頁
- drf內建了三個分頁器,分別應對三種分頁方式
- 內建的分頁類不能直接使用,需要繼承,定製一些引數後才能使用
2、三種分頁器的用法
模組地址:
三種分頁器在同一個父類中
from rest_framework.pagination import PageNumberPagination, CursorPagination, LimitOffsetPagination
檢視類程式碼:
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 指定分頁器
pagination_class = ‘指定使用的分分頁器’(需要匯入分頁器類)
2、1.自定義分頁器
from rest_framework.pagination import PageNumberPagination, CursorPagination, LimitOffsetPagination
# 第一種:通常用於web端(常規分頁器)
class CommonPageNumberPagination(PageNumberPagination):
# 每頁顯示2條
page_size = 2
# page=10 查詢第10頁的資料,每頁顯示2條
page_query_param = 'page'
# page=10&size=5 查詢第10頁,每頁顯示5條
page_size_query_param = 'size'
# 每頁最大顯示10條
max_page_size = 5
# 第二種:可以控制每頁顯示的數量(偏移分頁,用的較少)
class CommonLimitOffsetPagination(CursorPagination):
# 每頁顯示2條
default_limit = 3
# limit=3 取3條
limit_query_param = 'limit'
# offset=1 從第一個位置開始,取limit條
offset_query_param = 'offset'
# 最大顯示數
max_limit = 5
# 第三種:遊標分頁器(app常用,拉到哪裡顯示多少資料)
class CommonCursorPagination(CursorPagination):
# 查詢引數(可以隨便寫,需要在前端路由對上)
cursor_query_param = 'p'
# 每頁多少條
page_size = 2
# 排序的欄位
ordering = 'id'
前端對應搜尋方式:
#基本分頁方式(基本是這種,網頁端):
http://127.0.0.1:8000/api/v1/books/?page=2&size=3
# 偏移分頁 :從第一條開始,取4條
http://127.0.0.1:8000/api/v1/books/?limit=4&offset=1
# 遊標分頁:
http://127.0.0.1:8000/api/books/?p=cD0x