drf组件
认证组件
models.py
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
user_type = models.IntegerField(choice=(1,'超级管理员'),(2,'普通管理员'),(3,'用户'))
#token跟uesr表做一对一关联
class Token(models.Model):
user = models.OneToOneField(to='User')
token = models.CharField(max_length=32)
views.py
from rest_framewoke.views import APIView
import uuid
class Login(APIView):
def post(self,request):
response = {'code':100,'msg':'登入成功'}
name = request.data.get('name')
pwd = request.data.get('pwd')
try:
user = models.User.objects.filter(name=name,pwd=pwd).get()
#登入成功需要去token表中存数据,生成一个唯一的id
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'] = str(e)
return Response(response)
新建认证类
from rest_framework.authentication import BaseAuthentication
from rest_framwork.exceptions import AuthenticationFailed
from app01 import models
class TokenAuth(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当前登入对象
return token_obj.user,token_obj
else:
raise AuthenticationFailed('请先登入')
认证组件的使用
局部使用
from app01.MyAuth import TokenAuth
class Books(APIView):
#可以写多个认证类
authentication_classes = [TokenAuth,]
def get(self,request):
pass
全局使用
#在settings中配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.TokenAuth',] # app01.文件名.类名
}
局部禁用
from app01.MyAuth import TokenAuth
class Books(APIView):
authentication_classes = []
def get(self,request):
pass
根据源码可以知道:
- 如果在项目中的settings中配置了REST_FRAMEWORK,默认先从项目中的settings中取
- 如果取不到,就去默认的drf配置文件中取
- 如果在视图类中配置了,先去视图中配置的取
总结:
先取视图类中配置的=>项目settings中取=>默认配置
权限组件
新建一个权限类,继承BasePermission
from rest_framework.permission import BasePermission
class MyPermission(BasePermission):
message = '不是超级用户,查看不了' #将错误信息以中文的信息展示
#因为权限在认证之后执行的,所有能拿到request.user
def has_permission(self,request,view):
if request.user.user_type==1:
return True
else:
return False
权限组件的使用
局部使用
from app01.MyAuth import TokenAuth
class Books(APIView):
permission_classes = [MyPermission,]
def get(self,request):
pass
全局使用
#在settings中配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.TokenAuth',], # 应用名.文件名.类名
'DEFAULT_PERMISSION_CLASSES':['app01.MyAuth.MyPermission']
}
局部禁用
from app01.MyAuth import MyPermission
class Books(APIView):
permission_classes = []
def get(self,request):
pass
视图组件
基于mixins来封装的视图
第一种
url部分
url(r'^publish/$', views.PublishView.as_view()),
url(r'^publish/(?P<pk>d+)/$', views.PublishDetailView.as_view()),
from rest_framework.mixins import CreateModelMixin,ListModelMixin,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin
from rest_framework.generics import GenericAPIView
class PublishView(CreateModelMixins,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
第三种
url部分
url(r'^publish/$', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
url(r'^publish/(?P<pk>d+)/$',views.PublishView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset=models.Publish.objects.all()
serializer_class=PublishSerializers
自定义
url部分
url(r'^aa/$', views.PublishView.as_view({'get': 'aaa'})),
from rest_framework.viewsets import ViewSetMixin
from rest_framework.views import APIView
# ViewSetMixin 重写了as_view方法
class Test(ViewSetMixin,APIView): #注意先后顺序,因为APIView中也有as_view方法
def aaa(self,request):
return Response()
ModelViewSet:继承了
- mixins.CreateModelMixin
- mixins.RetrieveModelMixin
- mixins.UpdateModelMixin
- mixins.DestroyModelMixin
- mixins.ListModelMixin
- GenericViewSet
RetrieveUpdateDestroyAPIView:继承了
class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
ListCreateAPIView:继承了
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
了解
JWT:是JSON格式的被加密了的在字符串,服务器不保存session数据,所有数据都保存在客户端,每次请求都发回服务器
django的OneToOneField源码:本质就是继承了ForeignKey,初始化的时候kwargs['unique'] = True