認證組件
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})
類的繼承關系圖