文章目录
认证组件
只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件
表模型创建
class User(models.Model):
username=models.CharField(max_length=32)
password=models.CharField(max_length=32)
user_type=models.IntegerField(choices=((1,'超级管理员'),(2,'普通管理员'),(3,'普通用户')))
class UserToken(models.Model):
user=models.OneToOneField(to='User')
token=models.CharField(max_length=64)
认证组件
新建 MyAuths.py 文件,在文件内定义一个认证类(文件名和类名随意)
from rest_framework.authentication import BaseAuthentication
class MyAuth(BaseAuthentication):
def authenticate(self,request):
#写一些认证的逻辑
# print('我是认证类中的方法,只要配置了,一定会走我')
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('您没有登录')
局部使用
view.py 内的视图类中添加校验
# 用户必须登录之后才能访问获取所有图书接口
class Books(APIView):
# 可以写多个认证类
authentication_classes=[MyAuth,]
def get(self,request):
# request.user就是当前登录用户
print(request.user.name)
return Response('返回了所有图书')
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'] = '未知错误'
return Response(response)
总结:局部使用,只需要在视图类里加入:
authentication_classes = [TokenAuth, ]
全局使用
在settings文件中添加下面的参数
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}
添加全局校验后回对所有的视图类都进行校验,如果有视图类不需要进行校验可以在视图类中把校验设置为空列表
# 用户不登录也可以访问获取所有出版社信息
class Publish(APIView):
authentication_classes = []
def get(self,request):
print(request.user.name)
return Response('返回了所有出版社信息')
认证类使用顺序:先用视图类中的验证类,再用settings里配置的验证类,最后用默认的验证类
权限组件
只用超级用户才能访问指定的数据,普通用户不能访问,所以就要有权限组件对其限制
扫描二维码关注公众号,回复:
6727957 查看本文章
权限组件
class MyPermision(BasePermission):
message = '不是超级用户,查看不了'
def has_permission(self,request,view):
if request.user.user_type==1:
return True
else:
return False
局部使用
view.py 内的视图类中添加校验
class Books(APIView):
#只有超级用户才能访问该接口
permission_classes=[MyPermision,]
def get(self,request):
print(request.user.name)
return Response('返回了所有图书')
class Publish(APIView):
# 任何有户都有权限进行访问
permission_classes=[]
def get(self,request):
print(request.user.name)
return Response('返回了所有出版社信息')
局部使用只需要在视图类里加入:
permission_classes = [UserPermission,]
全局使用
在settings文件中添加下面的参数
REST_FRAMEWORK={
"DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",]
}
权限类使用顺序:先用视图类中的权限类,再用settings里配置的权限类,最后用默认的权限类
视图组件
首先写一个序列组件
class PublishSerializers(serializers.ModelSerializer):
class Meta:
model=models.Publish
fields='__all__'
基本视图
写一个出版社的增删查改resful接口
路由:
url(r'^publish/$', views.PublishView.as_view()),
url(r'^publish/(?P<pk>\d+)/$', views.PublishDetailView.as_view()),
视图:
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("")
mixin类和generice类编写视图
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)
使用generics 下ListCreateAPIView,RetrieveUpdateDestroyAPIView
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
上面三种方法的路由都是一样的。
使用ModelViewSet
路由:
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(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):
def aaa(self,request):
return Response()