rest認證元件,許可權元件,頻率元件,url註冊器,響應器元件,分頁器元件

Bound_w發表於2018-12-11

1.認證元件
  1.1 認證元件利用token來實現認證
  1.2 token認證的大概流程
  使用者登入===>獲取使用者名稱和密碼===>查詢使用者表 如果使用者存在,生成token,否則返回錯誤資訊
  1.3 示例

補充:自定義的序列化類

BookSerializer.py

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book

        fields = ('title',
                  'price',
                  'publish',
                  'authors',
                  'author_list',
                  'publish_name',
                  'publish_city'
                  )
        extra_kwargs = {
            'publish': {'write_only': True},
            'authors': {'write_only': True}
        }

    publish_name = serializers.CharField(max_length=32, read_only=True, source='publish.name')
    publish_city = serializers.CharField(max_length=32, read_only=True, source='publish.city')

    author_list = serializers.SerializerMethodField()

    def get_author_list(self, book_obj):
        # 拿到queryset開始迴圈 [{}, {}, {}, {}]
        authors = list()

        for author in book_obj.authors.all():
            authors.append(author.name)

        return authors
BookSerializer

models.py

 from django.db import models
    #使用者表
    
        class User(models.Model)
            
            username=models.CharField(max_length=32),
            password=models.CharFiels(max_length=32),
            user_type_entry=(
                (1,VIP),
                (2,SVIP),
                (3,VVIP),
            ),
            user_type=models.IntegerField(choices=user_type_entry)
            
            def __str__(self):
                return self.username
    
    #token表
        
        class UserToken(models.Model):
            user=models.OneToOneField('User',on_delete=models.CASADE)
            token=model.CharFields(max_length=128),
models.py

urls.py

from django.urls import re_path
        from serializer import views

        urlpatterns = [
            re_path(r'books/$', views.BookView.as_view({
                'get': 'list',
                'post': 'create'
            })),
            re_path(r'books/(?P<pk>\d+)/$', views.BookView.as_view({
                'get': 'retrieve',
                'put': 'update',
                'delete': 'destroy'
            })),
            re_path(r'user/$', views.UserView.as_view()),
            ]
urls.py

views.py

from django.http import JsonResponse
        from rest_framework.views import APIView
        from .models import (
            Book,
            Publish,
            Author,
            User,
            UserToken
        )
        #使用者登入認證
        class UserView(APIView):
            def post(self,request):
            response=dict()
            fields={"username","password"}
            user_info=dict()
            if fields.issubclass(set(request.data.keys()))
                for key in fields:
                    user_info[key]=request.data[key]
            user_instance=User.objects.filter(**user_info).first()
            #如果使用者名稱和密碼存在,建立或者更新token
            if user_info is not None:
                access_token=str(uuid.uuid4()).replace('-','')
                UserToken.objects.update_or_create    (user=user_instance,defaults={"token":access_token})
                response["status_code"]=200
                response["status_message"]='登入成功'
                response["status_token"]=access_token
                # response["status_role"]=user_instance.get_user_type_diaplay()
            else:
                response["status_code"]=201
                response["status_message"]="登入失敗,使用者名稱或密碼錯誤"
            #返回狀態
            return JsonResponse(response)
            
            
        #建立一個認證類
        方式一:
        class UserAuth():
            def authenticate_header(self,request):
                pass
                
            def authenticate(self,request):
                #獲取token
                user_token=request.query_params.get('token')
                try:
                    token=UserToken.objects.get(token=user_token)
                    return=token.user,token.token
                except Exception:
                    rais APIException('沒有認證')
            注意:必須寫authenticate_header和authenticate這兩個函式名,原始碼中有宣告,
                authenticate_header中不寫內容,但是必須書寫,authenticate中書寫邏輯
        方式二:
        from rest_framework.authentication import BaseAuthentication
        
        class UserAuth(BaseAuthentication):
            def authenticate(self,request):
                user_token=request.query_params.get("token")
                try:
                    token=UserToken.objects.get(token=user_token)

                    return token.user,token.token
                except Exception:
                    raise APIException("沒有認證")
        
        
        
        #訪問book表需要認證和許可權
        class BookView(ModelViewSet):
        #認證(只能是authentication_classes)
            authentication_classes = [UserAuth]
        #許可權(只能是permission_classes)
            permission_classes = [UserPerm]
        
            queryset = Book.objects.all()
            serializer_class = BookSerializer
views.py

2.許可權元件

views.py

2.1定義一個許可權類:
        class UserPerm():
        #自定義返回內容
            message="沒有許可權!"
            def has_permission(self,request,view):
                if request.user.user_type ==3:
                    return True
                return False
                
    2.2
        #訪問book表需要認證和許可權
        class BookView(ModelViewSet):
        #認證(只能是authentication_classes)
            authentication_classes = [UserAuth]
        #許可權(只能是permission_classes)
            permission_classes = [UserPerm]
        
            queryset = Book.objects.all()
            serializer_class = BookSerializer
views.py

 3.頻率元件

控制使用者訪問的頻率

    3.1頻率元件的使用
        -首先定義一個頻率類
        -匯入模組
        from rest_framework.throttling import SimpleRateThrottle
        -定義類
        class RateThrottle(SimpleRateThrottle)
            rate='5/m'#每分鐘訪問不能超過5次
            def get_cache_key(self,request,view):
                retuen self.get_ident(request)
                
        -指定一個頻率類
        class BookView(APIView):
            throttle_class=[RateThrottle]
        
    3.2利用FRF的簡單頻率來控制使用者訪問的頻率(全域性)
    -匯入模組
        from rest_framework.throttling import SimpleRateThrottle
    -定義一個頻率類,一定繼承SimpleRateThrottle
        class RateThrottle(SimpleRateThrottle):
            #指定訪問的頻率
            scope="visit_rate"
            #指定通過什麼方式來區分使用者
            def get_cache_key(self,request,view):
                return self.get_ident(request)
                
    -在全域性seetings中指定頻率類和訪問的頻率
        REST_FRAMEWORK={
        'DEFAULT_THROTTLE_CLASSES':("RateThrottle"),
        "DEFAULE_THROTTLE_RATES"":{
            "visit_rate":"5/m",
        }
        }
頻率元件的區域性使用和全域性使用的流程

4.url註冊器

一鍵建立url

    -匯入模組
        from django.urls import re_path,include
        import views
        from rest_framework import routers
    -生成一個註冊器的例項物件
        router=routers.DafaultRouter()
    -將需要生成的url介面註冊
        router.register(r"books",Views.BookView)
    -開始自動生成url
    urlpatterns=[
        re_path('^',include(router.urls)),
    ]
        
url註冊器的使用流程

5.響應器元件

    -匯入模組
        from rest_framework.renderers import JsonRender
    -指定返回類
        class BookView(APIView):
            render_classes=[JsonRender]
響應器元件的使用

6.分頁器元件

使用方法
    -匯入模組
        from rest_framework.pagination import PageNumberPagination
    -獲取資料
        books=Book.objects.all()
    -建立一個分頁器
        paginater=PageNumberPagination()
    -開始分頁
        paged_books=paginater.paginate_queryset(books,request)
    -開始序列化
        serialized_books=BookSerializer(paged_books,many=True)
    -返回資料
        return Response(serialized_books.data)
    
    -分頁器的區域性實現
    -匯入模組
        from rest_framework.pagination import PageNumberPagination
    -自定義一個分頁類,要繼承PageNumberPagination
        class MyPagination(PageNumberPagination):
            page_aize=2#每頁顯示2條資料
            page_query_param='p'
            page_size_query_param='size'
            max_page_size=5#最多顯示5條資料
        
    -例項化一個分頁類
        paginater=MyPagination()
    -開始分頁
        paged_books=paginater.paginate_queryset(books,request)
    -開始序列化
        serialized_books=BookSerializer(paged_books,many=True)
    -返回資料
        return Response(serialized_books.data)
    
分頁器元件的使用以及區域性使用

 

相關文章