认证组件
0.token
#login视图中认证和token 的存储 class Login(APIView): authentication_classes = [] def post(self,request): response={'code':100,'msg':'登录成功'} name=request.data.get('name') pwd=request.data.get('pwd') try: #get 有且只有一条才不报错,其他都抛异常 user=models.User.objects.filter(name=name,pwd=pwd).get() #登录成功,需要去token表中存数据 #生成一个唯一的idhg token=uuid.uuid4() models.Token.objects.update_or_create(user=user,defaults={'token':token}) response['token']=token except ObjectDoesNotExist as e: response['code']=101 response['msg']='用户名或密码错误' except Exception as e: response['code'] = 102 # response['msg'] = '未知错误' response['msg'] = str(e) return Response(response)
1.写一个认证类,继承BaseAuthentication
from rest_framework.authentication import BaseAuthentication
from app01 import models
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.permissions import BasePermission
class MyAuth(BaseAuthentication): def authenticate(self,request): #写一些认证的逻辑 token=request.GET.get('token') token_obj=models.Token.objects.filter(token=token).first() if token_obj: #有值表示登录了 #token_obj.user 当前登录的user对象 return token_obj.user,token_obj else: #没有值,表示没有登录,抛异常 raise AuthenticationFailed('您没有登录')
-局部使用
在视图类中写一个列表
authentication_classes=[Myauth,]
-全局使用
在settings.py中配置
REST_FRAMEWORK={"DEFAULT_AUTHENTICATION_CLASSES":["app01.MyAuths.MyAuth",]}
-局部禁用
在视图中写入authentication_classes = []
-源码中可以观察到的点
-如果在项目的setting.py中配置了REST_FRAMEWORK,默认先从项目的setting中取
-如果取不到,才去默认的drf(djangorestframework)配置文件中取
-如果用户在视图类中配置了,先去用户配置的取
-总结
先取视图类中配置的----》项目setting中取----》默认配置
接口创建前置工作
先在models.py中创建好数据库字段模型(只针对我下面的代码)
from django.db import models # Create your models here. class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish_date = models.DateField(null=True) xx=models.IntegerField(choices=((0,'文学类'),(1,'情感类')),default=1,null=True) publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True) authors=models.ManyToManyField(to='Author') def __str__(self): return self.name def test(self): return 'xxx' class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name
在views中导入需要的序列化组件
from django.shortcuts import render from rest_framework.response import Response from rest_framework import serializers from managements import models from rest_framework.views import APIView # Create your views here. class PublishSerializers(serializers.ModelSerializer): class Meta: model=models.Publish fields='__all__'
方法一:基本视图方法
基本视图 class PublishView(APIView): def get(self, request): publish_list = models.Publish.objects.all() bs = PublishSerializers(publish_list, many=True) # 序列化数据 return Response(bs.data) def post(self, request): # 添加一条数据 print(request.data) bs=PublishSerializers(data=request.data) if bs.is_valid(): bs.save() # 生成记录 return Response(bs.data) else: return Response(bs.errors) class PublishDetailView(APIView): def get(self,request,pk): publish_obj=models.Publish.objects.filter(pk=pk).first() bs=PublishSerializers(publish_obj,many=False) return Response(bs.data) def put(self,request,pk): publish_obj = models.Publish.objects.filter(pk=pk).first() bs=PublishSerializers(data=request.data,instance=publish_obj) if bs.is_valid(): bs.save() # update return Response(bs.data) else: return Response(bs.errors) def delete(self,request,pk): models.Publish.objects.filter(pk=pk).delete() return Response("")
方法二:基于mixins来封装的视图
基于mixins来封装的视图 from rest_framework.mixins import CreateModelMixin,ListModelMixin,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin from rest_framework.generics import GenericAPIView class PublishView(CreateModelMixin,ListModelMixin,GenericAPIView): queryset = models.Publish.objects.all() serializer_class = PublishSerializers def post(self,request, *args, **kwargs): return self.create(request, *args, **kwargs) def get(self,request, *args, **kwargs): return self.list(request, *args, **kwargs) class PublishDetailView(RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin,GenericAPIView): queryset = models.Publish.objects.all() serializer_class = PublishSerializers 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)
方法三:通过封装好的方法两个类来完成
from rest_framework.generics import CreateAPIView,ListCreateAPIView,DestroyAPIView,RetrieveUpdateDestroyAPIView class PublishView(ListCreateAPIView): queryset = models.Publish.objects.all() serializer_class = PublishSerializers class PublishDetailView(RetrieveUpdateDestroyAPIView): queryset = models.Publish.objects.all() serializer_class = PublishSerializers
方法四:一个类完成五种方法
from django.views import View from rest_framework.viewsets import ModelViewSet class PublishView(ModelViewSet): queryset=models.Publish.objects.all() serializer_class=PublishSerializers from rest_framework.viewsets import ViewSetMixin from rest_framework.views import APIView # ViewSetMixin 重写了as_view方法 class Test(ViewSetMixin,APIView): def aaa(self,request): return Response({'code':100})
类的继承关系图