日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Django-認證-權限控制-節流-分頁-過濾

作者:lonely-hermit 更新時間: 2022-05-13 編程語言

簡單來講,認證確定了你是誰

權限確定了你能不能訪問某個接口

限制確定了你訪問某個接口的最高頻率

一、認證

身份驗證是將傳?請求與?組標識憑據(例如請求來?的?戶或其簽名的令牌)相關聯的機制。然后權限和限制組件決定是否拒絕這個請求。認證本身不會允許或拒絕傳?的請求,它只是簡單識別請求攜帶的憑證。

REST framwork不僅自己有著開箱即用的驗證方案,還允許你自己實現驗證方案

1.1、自定義認證

要實現?定義的認證?案,要繼承BaseAuthentication類并且重 寫.authenticate(self, request) ?法。如果認證成功,該?法應返回(user, auth)的 ?元元組,否則返回None,還可以拋出AuthenticationFailed異常

在App下,創建authentications.py,然后?定義認證類

from django.core.cache import cache
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

from app.models import Students


class appAuthentication(BaseAuthentication):
    def authenticate(self, request):
        token = request.query_params.get('token')
        if not token:
            raise AuthenticationFailed('沒有 token')
        username = cache.get(token)
        if not username:
            raise AuthenticationFailed('token 過期')
        try:
            student = Students.objects.filter(stu_name=username)
            if student:
                return student, None
            else:
                return None
        except Exception as e:
            print(e)
            raise AuthenticationFailed('token 不合法')

urls.py

urlpatterns = [
    path('getToken/', views.getToken.as_view(), name='getToken'),

    path('testToken/',views.testToken.as_view(),name='testToken'),
]

views.py

class getToken(APIView):
    # 我們的get請求直接給前端一個token,用于測試
    def get(self, request):
        username = '123'
        token = token_confirm.generate_validate_token(username=username)
        mycache = cache.get(token)
        if mycache:
            token = mycache
        else:
            cache.set(token, token, settings.CACHE_TIMEOUT)
        return HttpResponse('http://127.0.0.1:8000/testToken?token=' + token)

class testToken(APIView):
    authentication_classes = (appAuthentication,)

    def get(self,request):
        return HttpResponse('OK')

我們訪問getToken可以得到需要驗證的網址,然后這個網址登錄可以看到我們登錄后返回的信息,OK

我們也可以進行全局級別的認證,只是這樣的話需要我們配置一下

settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'App.authentications.MyAuthentication', 
    )
}

二、權限控制

權限控制可以限制?戶對于視圖的訪問和對于具體數據對象的訪問

在執?視圖的dispatch()?法前,會先進?視圖訪問權限的判斷

在通過get_object()獲取具體對象時,會進?對象訪問權限的判斷

2.1、系統內置的權限

AllowAny 允許所有?戶

IsAuthenticated 僅通過認證的?戶

IsAdminUser 僅管理員?戶

IsAuthenticatedOrReadOnly 認證的?戶可以完全操作,否則只能get讀取

2.2、自定義權限控制

我們自己寫一個permission.py

# 寫?個繼承?BasePermission
class WomanPerssion(BasePermission):
    # 復寫??的has_permission函數
    def has_permission(self, request, view):
        # request.user是認證后拿到的元組第一個值
        print(request.user)
        if request.user != None:
            # 判斷當前?戶是不是女性用戶
            return request.user.stu_gender == 'w'
        	# 返回True就是驗證通過,返回False就是驗證失敗
        return False

我們的視圖函數只需要再加一句話

class testToken(APIView):
    authentication_classes = (appAuthentication,)
    permission_classes = (WomanPerssion,)

    def get(self, request):
        return HttpResponse('OK')

如果要進行全局的驗證的話

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'App.authentications.MyAuthentication', 
    ),
    "DEFAULT_PERMISSION_CLASSES":
        ["app.permission.WomanPerssion",]
}

三、節流器

節流類似于權限,?于控制客戶端可以對API發出的請求的速率

mythrottle.py

from rest_framework.throttling import SimpleRateThrottle


class VisitThrottle(SimpleRateThrottle):
    # 轉換頻率每分鐘5次,轉換頻率 = num/duration,其中duration可以是s(秒)、m(分)、h(?時)、d(天)
    rate = '5/m'
    score = 'vistor'

    # 返回?個唯?標示?以區分不同的?戶
    def get_cache_key(self, request, view):

        return self.get_ident(request)  # 返回?戶i

視圖級別的控制

class testToken(APIView):
    authentication_classes = (appAuthentication,)
    permission_classes = (WomanPerssion,)
    throttle_classes = (VisitThrottle,)

    def get(self, request):
        return HttpResponse('OK')

全局的控制

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'App.authentications.MyAuthentication', 
    ),
    "DEFAULT_PERMISSION_CLASSES":
        ["app.permission.WomanPerssion",],
    'DEFAULT_THROTTLE_CLASSES': ['apps.mythrottle.VisitThrottle'],
    'DEFAULT_THROTTLE_RATES': {
         'vistor': '3/m',
         'anon': '10/day',# 匿名?戶
   }
}

DEFAULT_THROTTLE_RATES 可以使? second , minute , hour 或 day 來指明周期

3.1、可選限流器

3.1.1、AnonRateThrottle

限制所有匿名未認證?戶,使?IP區分?戶。使? DEFAULT_THROTTLE_RATES[‘anon’] 來設置頻次

3.1.2、UserRateThrottle

限制認證?戶,使?User id 來區分。 使? DEFAULT_THROTTLE_RATES[‘user’] 來設置頻次

3.1.3、ScopedRateThrottle

限制?戶對于每個視圖的訪問頻次,使?ip或user id

eg:

class ContactListView(APIView):
    throttle_scope = 'contacts'
    
REST_FRAMEWORK = {
     'DEFAULT_THROTTLE_CLASSES': (
     'rest_framework.throttling.ScopedRateThrottle',
     ),
     'DEFAULT_THROTTLE_RATES': {
     	'contacts': '1000/day',
     	'uploads': '20/day'
     }
}

四、分頁Pagination

REST framework提供了分?的?持。 我們可以在配置?件中設置全局的分??式

REST_FRAMEWORK = {
	'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10 # 每?數?
}

4.1、自定義分頁類

也可通過?定義Pagination類,來為視圖添加不同分??為。在視圖中通過 pagination_clas 屬性來指明

注意:如果在視圖內關閉分?功能,只需在視圖內設置

pagination_class = None

4.2、PageNumberPagination

前端訪問形式GET http://127.0.0.1:8000/studentView/?page=1

可以在?類中定義的屬性:
page_size 每?數?
page_query_param 前端發送的?數關鍵字名,默認為"page"
page_size_query_param 前端發送的每?數?關鍵字名,默認為None
max_page_size 前端最多能設置的每?數量

serializer.py

from rest_framework import serializers
from app.models import Students


class studentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Students
        # 包含模型中所有字段
        fields = '__all__'

models.py

class Students(models.Model):
    stu_num = models.CharField(primary_key=True, max_length=8)
    stu_name = models.CharField(max_length=40)
    stu_gender = models.CharField(max_length=4)
    stu_age = models.IntegerField()
    cid = models.ForeignKey(Classes, models.DO_NOTHING, db_column='cid', blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'students'

urls.py

urlpatterns = [
    path('studentView/', views.studentView.as_view(), name='studentView'),
]

views.py

class studentView(ListAPIView):
    queryset = Students.objects.all()
    serializer_class = studentSerializer
    pagination_class = studentPagination

pagination.py

from rest_framework.pagination import PageNumberPagination

class studentPagination(PageNumberPagination):
    page_size_query_param = 'page_size'
    max_page_size = 1
    page_size = 1
    page_query_param = 'pagepage'

我們再前端訪問就可以得到我們的數據了

4.3、LimitOffsetPagination

前端的訪問形式GET http://127.0.0.1:8000/studentView/?limit=100&offset=400

可以在?類中定義的屬性: 
default_limit 默認限制,默認值與 PAGE_SIZE 設置?直 
limit_query_param limit參數名,默認'limit' 
offset_query_param offset參數名,默認'offset' 
max_limit 最?limit限制,默認None

他的設置方法和前面的一致

五、過濾

對于列表數據可能需要根據字段進?過濾,我們可以通過添加django-fitlter擴展來增強?持。官?地址:https://django-filter.readthedocs.io/en/master/index.html

5.1、安裝

pip install django-filter

5.2、配置

settings.py

INSTALLED_APPS = [
    'django_filters', # 需要注冊應?,
]
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

5.3、視圖設置

class studentView(ListAPIView):
    queryset = Students.objects.all()
    serializer_class = studentSerializer
    filter_fields = ('stu_name', 'stu_gender')

其他的和上面的保持一致,我們訪問下面這個地址

GET http://127.0.0.1:8000/studentView/?stu_gender=w

5.4、自定義過濾類

customfilter.py

import django_filters
from django_filters import rest_framework as filters
from app.models import Students


class studentsFilters(django_filters.FilterSet):
    class Meta:
        # field_name = "bread" 模型中的字段名; lookup_expr是運算,gte表示 >=
        min_read = filters.NumberFilter(field_name="bread", lookup_expr='gte')
        ax_read = filters.NumberFilter(field_name="bread", lookup_expr='lte')
        model = Students
        fields = {
            'stu_age': ['icontains'],  # 鍵是字段名,列表?是查詢進?運算
        }

views.py

class studentView(ListAPIView):
    queryset = Students.objects.all()
    serializer_class = studentSerializer
    filter_class = studentsFilters  # 指定過濾類
  • field_name 數據庫中字段名
  • lookup_expr 操作(和django的orm中運算符?樣) 關系運算符:gte(>=) 、gt(>)、 lte(<=)、 lt(<) 字符串; icontains(忽略??寫,包含)
  • model指定模型
  • fields可以指定過濾字段

訪問測試:

http://127.0.0.1:8000/studentView/?stu_gender=w

http://127.0.0.1:8000/studentView/?minage=0&maxage=2

這個其實并不重要,我們可以直接數據查詢返回

六、自動生成接口文檔

6.1、安裝

pip install coreapi

6.2、配置

settings.py

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
}

6.3、設置接??檔訪問路徑

在總路由中添加接??檔路徑。

?檔路由對應的視圖配置為 rest_framework.documentation.include_docs_urls ,

參數 title 為接??檔?站的標題

6.4、文檔描述說明定義

6.4.1、單一方法視圖

單??法的視圖,可直接使?類視圖的?檔字符串,如

class BookListView(generics.ListAPIView):
    """
    返回所有圖書信息.
    """
6.4.1、多個方法視圖
class BookListCreateView(generics.ListCreateAPIView):
     """
     get:
     返回所有圖書信息.
     post:
     新建圖書.
     """
6.4.3、視圖集

對于視圖集ViewSet,仍在類視圖的?檔字符串中分開定義,但是應使?action 名稱區分,

class BookInfoViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin, GenericViewSet):
     """
     list:
     返回圖書列表數據
     retrieve:
     返回圖書詳情數據
     latest:
     返回最新的圖書數據
     read:
     修改圖書的閱讀量
     """
6.4.4、網址訪問

http://127.0.0.1:8000/docs/

原文鏈接:https://blog.csdn.net/weixin_43903639/article/details/122991938

欄目分類
最近更新