drf-视图组件 认证组件

一、视图组件:

基础块:

from rest_framework.response import Response
from rest_framework import serializers
from app01.models import *
from rest_framework.views import APIView
from rest_framework.exceptions import AuthenticationFailed
import uuid
from rest_framework.authentication import BaseAuthentication


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
View Code

1、基本视图,不采用rest_framework提供的组件

class Booksview(APIView):
    def get(self, request, *args, **kwargs):
        respones = {'status': 100, 'msg': '查询成功'}
        book_list = Book.objects.all()
        book_ll = BookSerializer(instance=book_list, many=True)
        respones['data'] = book_ll.data
        return Response(respones)

    def post(self, request, *args, **kwargs):
        respones = {'status': 100, 'msg': '新增成功'}
        book = BookSerializer(data=request.data, many=False)
        if book.is_valid():
            book.save()
            respones['data'] = book.data
        else:
            respones['msg'] = book.errors
        return Response(respones)


class Bookview(APIView):
    def get(self, request, pk, *args, **kwargs):
        respones = {'status': 100, 'msg': '查询成功'}
        book_list = Book.objects.filter(pk=pk)
        book_ll = BookSerializer(instance=book_list, many=True)
        respones['data'] = book_ll.data
        return Response(respones)

    def put(self, request, pk, *args, **kwargs):
        respones = {'status': 100, 'msg': '修改成功'}
        book = Book.objects.filter(pk=pk).first()
        book_ll = BookSerializer(instance=book, data=request.data)
        if book_ll.is_valid():
            book_ll.save()
            respones['data'] = book_ll.data
        else:
            respones['msg'] = book_ll.errors
        return Response(respones)

    def delete(self, request, pk, *args, **kwargs):
        book = Book.objects.filter(pk=pk).delete()
        return HttpResponse("")
View Code

 2、基于mixins,generics编写的视图:

from rest_framework.mixins import *
from rest_framework.generics import GenericAPIView


class BooksView(ListModelMixin, CreateModelMixin, GenericAPIView):
    queryset = Book.objects
    serializer_class = BookSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)


class BookView(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
    queryset = Book.objects
    serializer_class = BookSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
View Code

3、基于generics下的ListAPIView, CreateAPIView, UpdateAPIView, DestroyAPIView, RetrieveAPIView编写的视图:

from rest_framework.generics import ListAPIView, CreateAPIView, UpdateAPIView, DestroyAPIView, RetrieveAPIView


class BooksView(ListAPIView, CreateAPIView):
    queryset = Book.objects
    serializer_class = BookSerializer


class BookView(UpdateAPIView, DestroyAPIView, RetrieveAPIView):
    queryset = Book.objects
    serializer_class = BookSerializer
View Code

4、基于viewsets编写的视图类:

from rest_framework.viewsets import ModelViewSet


class BooksView(ModelViewSet):
    queryset = Book.objects
    serializer_class = BookSerializer

# 注: 因为BooksView中包含了5个方法,所以在路由层需要告诉视图类不同请求所对应应该调用的函数,因此路由层有所变化。
视图层

路由层:

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^books/$', views.BooksView.as_view({'get': "list", "post": 'create'})),
    re_path('^books/(?P<pk>\d+)', views.BooksView.as_view({"get": 'retrieve', 'put': 'update', 'delete': 'destroy'}))
]
路由层

二、认证组件:

案例示范:

1、models层

# 创建一个可登录的用户表
class User(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.CharField(max_length=20)
    password = models.CharField(max_length=20)


# 用户登陆验证携带信息
class Usertoken(models.Model):
    user = models.OneToOneField(to='User', on_delete=models.CASCADE)
    token = models.CharField(max_length=64)
View Code

2、为登录配置的视图类:

import uuid
class Login(APIView):
    def post(self, request):
        back_msg = {'status': '100', 'msg': 'login success'}
        try:
            usr = request.data.get('user', None)
            password = request.data.get('password', None)
            print(usr, password)
            print(request)
            user = User.objects.get(user=usr, password=password)
            if user:
                token = uuid.uuid4()
                Usertoken.objects.update_or_create(user=user, defaults={'token':token})
                back_msg['token'] = token
            else:
                back_msg['msg'] = 'login failed'
        except Exception as e:
            back_msg['msg'] = str(e)
        return Response(back_msg)
View Code

3、登录验证类:

class TokenAuth():
    def authenticate(self, request):
        token = request.GET.get('token', None)
        token_obj = Usertoken.objects.filter(token=token).first()
        if token_obj:
            return None
        else:
            raise AuthenticationFailed('认证失败')

    def authenticate_header(self, request):
        pass

# 可以继承django内部封装好的
from rest_framework.authentication import BaseAuthentication
class TokenAuth(BaseAuthentication):
    def authenticate(self, request):
        token = request.GET.get('token', None)
        token_obj = Usertoken.objects.filter(token=token).first()
        if token_obj:
            return token_obj.user, token_obj
        else:
            raise AuthenticationFailed('认证失败')
View Code

4、需验证的视图类:

class Book(APIView):
    authentication_classes = [TokenAuth]

    def get(self, request):
        return Response('ok')
View Code

 

posted @ 2019-03-27 20:13  zhao_peng  阅读(197)  评论(0编辑  收藏  举报