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__'
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("")
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)
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
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)
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)
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('认证失败')
4、需验证的视图类:
class Book(APIView): authentication_classes = [TokenAuth] def get(self, request): return Response('ok')