版本
DRF中版本
导入
from rest_framework.versioning import
全局配置版本控制系统
是在 URL加查询参数
# DRF的配置
REST_FRAMEWORK = {
# 配置默认使用的版本控制类
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'DEFAULT_VERSION': 'v1', # 默认的版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 有效的版本
'VERSION_PARAM': 'version', # 版本的参数名与URL conf中一致
}
URl
url(r'(?P<version>[v1|v2]+)/books/$', views.BookListView.as_view()),
视图:
class BookListView(ListCreateAPIView):
"""查看列表和创建"""
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
# 只要配置了版本 在视图中就能通过 request.version
def get_serializer_class(self):
"""获取当前序列化类的方法"""
# 根据版本的不同返回不同的序列化类
print(self.request.version)
if self.request.version == 'v1':
return BookSerializerVersion1
return self.serializer_class
局部配置 一般都是全局配置
注意,通常我们是不会单独给某个视图设置版本控制的,如果你确实需要给单独的视图设置版本控制,你可以在视图中设置versioning_class属性,如下:
class PublisherViewSet(ModelViewSet):
...
versioning_class = URLPathVersioning
认证
接下类我们就自己动手实现一个基于Token的认证方案:
自定义Token认证
表
定义一个用户表和一个保存用户Token的表:
class UserInfo(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
vip = models.BooleanField(default=False)
token = models.CharField(max_length=128,null=True,blank=True)
url
url(r'users/',include('auth_demo.urls')),
urlpatterns = [
url(r'reg/$',views.RegView.as_view()),
url(r'login/$',views.LoginView.as_view()),
url(r'test_auth/$',views.TesAuthView.as_view()),
]
登录和注册 views
from django.shortcuts import render
from rest_framework.views import APIView
from auth_demo import models
from rest_framework.response import Response
import uuid
class RegView(APIView):
def post(self, request):
# 获取用户注册的数据
name = request.data.get('name')
pwd = request.data.get('pwd')
re_pwd = request.data.get('re_pwd')
if name and pwd:
if pwd == re_pwd:
models.UserInfo.objects.create(name=name, pwd=pwd)
return Response('注册成功')
else:
return Response('两次密码不正确')
else:
return Response('无效参数')
class LoginView(APIView):
def post(self, request):
name = request.data.get('name')
pwd = request.data.get('pwd')
if name and pwd:
user_obj = models.UserInfo.objects.filter(name=name, pwd=pwd).first()
if user_obj:
# 生成token 保存在用户表, 给用户返回
token = uuid.uuid1().hex
user_obj.token = token
user_obj.save()
return Response({'error_on': 1, 'error': token})
else:
return Response({'error_on': 1, 'error': '用户名或密码错误'})
else:
return Response('无效参数')
局部配置认证
from auth_demo.auth import MyAuth
# 登录之后才能看到的数据接口
class TesAuthView(APIView):
authentication_classes = [MyAuth, ] # 局部配置认证
def get(self, request):
return Response('这里只能是登陆后才能看到的地方')
全局配置认证 不推荐用
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['auth_demo.auth.MyAuth', ]
}
自定义认证
from rest_framework.authentication import BaseAuthentication
from auth_demo import models
from rest_framework.exceptions import AuthenticationFailed#别人写的抛出异常
class MyAuth(BaseAuthentication):
def authenticate(self, request):
#拿到页面?后面的数据
token = request.query_params.get('token')
if token:
user_obj = models.UserInfo.objects.filter(token=token).first()
if user_obj:
# token是有效的,记住要对象和token
return user_obj,token
else:
# 抛出异常
raise AuthenticationFailed('无效的token')
else:
raise AuthenticationFailed('请求的URL中必须携带token参数')
权限
自定义一个权限组件
from rest_framework.permissions import BasePermission
from auth_demo import models
class MyPermission(BasePermission):
#提示
message = '这是vip才能访问'
def has_permission(self, request, view):
# 如果你是VIP才有权限访问
# request.user:当前经过认证的用户对象
if not request.auth: #在权限里先判断有没有通过认证
return False
if request.user.vip:
return True
else:
return False
全局配置
'DEFAULT_PERMISSION_CLASSES': ['auth_demo.permissions.MyPermission', ]
局部配置
from auth_demo.auth import MyAuth
from auth_demo.permissions import MyPermission
# 登录之后才能看到的数据接口
class TesAuthView(APIView):
authentication_classes = [MyAuth, ] # 局部配置认证
permission_classes = [MyPermission, ]#局部配置权限
def get(self, request):
return Response('这里只能是登陆后才能看到的地方')