@

目录

一 路由Routers

对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。

REST framework提供了两个router

  • SimpleRouter
  • DefaultRouter

1.1 使用方法

1) 创建router对象,并注册视图集,例如

from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'router_stu', StudentModelViewSet, base_name='student')

register(prefix, viewset, base_name)

  • prefix 该视图集的路由前缀
  • viewset 视图集
  • base_name 路由别名的前缀

如上述代码会形成的路由如下:

^books/$    name: book-list
^books/{pk}/$ name: book-detail

2)添加路由数据

可以有两种方式:

urlpatterns = [
...
]
urlpatterns += router.urls

urlpatterns = [
...
url(r'^', include(router.urls))
]

1.2 代码演示

使用路由类给视图集生成了路由地址

# 必须是继承ModelViewSet的视图类才能自动生成路由
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
class StudentModelViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
# 这种方法不会自动生成,需要用action配置
def login(self,request):
"""学生登录功能"""
print(self.action)
return Response({"message":"登录成功"})

路由代码:

from django.urls import path, re_path
from . import views
urlpatterns = [
...
] """使用drf提供路由类router给视图集生成路由列表"""
# 实例化路由类
# drf提供一共提供了两个路由类给我们使用,他们用法一致,功能几乎一样
from rest_framework.routers import DefaultRouter
router = DefaultRouter() # 注册视图集
# router.register("路由前缀",视图集类)
router.register("router_stu",views.StudentModelViewSet) # 把生成的路由列表追加到urlpatterns
print( router.urls )
urlpatterns += router.urls

上面的代码就成功生成了路由地址[增/删/改/查一条/查多条的功能],但是不会自动我们在视图集自定义方法的路由。

所以我们如果也要给自定义方法生成路由,则需要进行action动作的声明。

1.2 视图集中附加action的声明

在视图集中,如果想要让Router自动帮助我们为自定义的动作生成路由信息,需要使用rest_framework.decorators.action装饰器。

以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。

action装饰器可以接收两个参数:

  • methods: 声明该action对应的请求方式,列表传递
  • detail

    : 声明该action的路径是否与单一资源对应,及是否是
xxx/<pk>/action方法名/

True 表示路径格式是xxx/<pk>/action方法名/

False 表示路径格式是xxx/action方法名/

举例:

from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action class StudentModelViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer # methods 设置当前方法允许哪些http请求访问当前视图方法
# detail 设置当前视图方法是否是操作一个数据
# detail为True,表示路径名格式应该为 router_stu/{pk}/login/
@action(methods=['get'], detail=False)
def login(self, request):
return Response({'msg':'登陆成功'}) @action(methods=['put'], detail=True)
def get_new_5(self, request,pk):
return Response({'msg':'获取5条数据成功'})

由路由器自动为此视图集自定义action方法形成的路由会是如下内容:

^router_stu/get_new_5/$    name: router_stu-get_new_5
^router_stu/{pk}/login/$ name: router_stu-login

1.3 路由router形成URL的方式

1) SimpleRouter





2)DefaultRouter





DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。

认证权限频率

为了方便接下来的学习,我们创建一个新的子应用 opt

python manage.py startapp opt

因为接下来的功能中需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员.

python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py createsuperuser



创建管理员以后,访问admin站点,先修改站点的语言配置

settings.py

LANGUAGE_CODE = 'zh-hans'  # 中文

TIME_ZONE = 'Asia/Shanghai' # 时区是亚洲上海

USE_I18N = True # 国际化

USE_L10N = True # 本地化

USE_TZ = True # 数据库是否使用TIME_ZONE,True表示使用上海的时区,False表示不使用,使用UTC时间,然后转成上海,会差8个小时



访问admin 站点效果:

一 认证Authentication

1.1 自定义认证方案

1.1.1 编写models

# models.py
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)

1.1.2 新建认证类

from rest_framework.authentication import BaseAuthentication
class TokenAuth():
def authenticate(self, request):
token = request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
if token_obj:
return
else:
raise AuthenticationFailed('认证失败')
def authenticate_header(self,request):
pass

1.1.3 编写视图

def get_random(name):
import hashlib
import time
md=hashlib.md5()
md.update(bytes(str(time.time()),encoding='utf-8'))
md.update(bytes(name,encoding='utf-8'))
return md.hexdigest()
class Login(APIView):
def post(self,reuquest):
back_msg={'status':1001,'msg':None}
try:
name=reuquest.data.get('name')
pwd=reuquest.data.get('pwd')
user=models.User.objects.filter(username=name,password=pwd).first()
if user:
token=get_random(name)
models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
back_msg['status']='1000'
back_msg['msg']='登录成功'
back_msg['token']=token
else:
back_msg['msg'] = '用户名或密码错误'
except Exception as e:
back_msg['msg']=str(e)
return Response(back_msg) class Course(APIView):
authentication_classes = [TokenAuth, ] def get(self, request):
return HttpResponse('get') def post(self, request):
return HttpResponse('post')

1.1.4 全局使用

REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}

1.1.5 局部使用

#局部使用,只需要在视图类里加入:
authentication_classes = [TokenAuth, ]

1.2 内置认证方案(需要配合权限使用)

可以在配置文件中配置全局默认的认证方案

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', # session认证
'rest_framework.authentication.BasicAuthentication', # 基本认证
)
}

也可以在每个视图中通过设置authentication_classess属性来设置

from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIView class ExampleView(APIView):
# 类属性
authentication_classes = [SessionAuthentication, BasicAuthentication]
...

认证失败会有两种可能的返回值:

  • 401 Unauthorized 未认证
  • 403 Permission Denied 权限被禁止

二 权限Permissions

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。

  • 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
  • 在通过get_object()获取具体对象时,会进行模型对象访问权限的判断

2.1 自定义权限

2.1.1 编写权限类

# 限制只有超级用户能访问
from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
message = '不是超级用户,查看不了'
def has_permission(self, request, view):
# user_type = request.user.get_user_type_display()
# if user_type == '超级用户':
# 权限在认证之后,所以能取到user
user_type = request.user.user_type
print(user_type)
if user_type == 1:
return True
else:
return False

2.1.2 全局使用

REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
"DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",]
}

2.1.3 局部使用

# 局部使用只需要在视图类里加入:
permission_classes = [UserPermission,]

2.1.4 说明


如需自定义权限,需继承rest_framework.permissions.BasePermission父类,并实现以下两个任何一个方法或全部
- `.has_permission(self, request, view)`
是否可以访问视图, view表示当前视图对象 - `.has_object_permission(self, request, view, obj)`
是否可以访问数据对象, view表示当前视图, obj为数据对象

2.2 内置权限

2.2.1 内置权限类

from rest_framework.permissions import AllowAny,IsAuthenticated,IsAdminUser,IsAuthenticatedOrReadOnly
- AllowAny 允许所有用户
- IsAuthenticated 仅通过认证的用户
- IsAdminUser 仅管理员用户
- IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。

2.2.2 全局使用

可以在配置文件中全局设置默认的权限管理类,如

REST_FRAMEWORK = {
.... 'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}

如果未指明,则采用如下默认配置

'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)

2.2.3 局部使用

也可以在具体的视图中通过permission_classes属性来设置,如

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView class ExampleView(APIView):
permission_classes = (IsAuthenticated,)
...

2.2.4 实际操作

# 创建超级用户,登陆到admin,创建普通用户(注意设置职员状态,也就是能登陆)
# 全局配置IsAuthenticated
# setting.py
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
# urls.py
path('test/', views.TestView.as_view()),
# views.py
class TestView(APIView):
def get(self,request):
return Response({'msg':'个人中心'})
# 登陆到admin后台后,直接访问可以,如果没登陆,不能访问 ##注意:如果全局配置了
rest_framework.permissions.IsAdminUser
# 就只有管理员能访问,普通用户访问不了

三 限流Throttling

可以对接口访问的频次进行限制,以减轻服务器压力。

一般用于付费购买次数,投票等场景使用.

3.1 自定义频率类

3.1.1 编写频率类

# 自定义的逻辑
#(1)取出访问者ip
#(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
#(3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
#(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
#(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
class MyThrottles():
VISIT_RECORD = {}
def __init__(self):
self.history=None
def allow_request(self,request, view):
#(1)取出访问者ip
# print(request.META)
ip=request.META.get('REMOTE_ADDR')
import time
ctime=time.time()
# (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
if ip not in self.VISIT_RECORD:
self.VISIT_RECORD[ip]=[ctime,]
return True
self.history=self.VISIT_RECORD.get(ip)
# (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
while self.history and ctime-self.history[-1]>60:
self.history.pop()
# (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
# (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
if len(self.history)<3:
self.history.insert(0,ctime)
return True
else:
return False
def wait(self):
import time
ctime=time.time()
return 60-(ctime-self.history[-1])

3.1.2 全局使用

REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES':['app01.utils.MyThrottles',],
}

3.1.3 局部使用

#在视图类里使用
throttle_classes = [MyThrottles,]

3.2 内置频率类

3.2.1 根据用户ip限制

#写一个类,继承自SimpleRateThrottle,(根据ip限制)
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope = 'luffy'
def get_cache_key(self, request, view):
return self.get_ident(request)
#在setting里配置:(一分钟访问三次)
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES':{
'luffy':'3/m' # key要跟类中的scop对应
}
} # 可以全局使用,局部使用

了解:错误信息中文显示

class Course(APIView):
authentication_classes = [TokenAuth, ]
permission_classes = [UserPermission, ]
throttle_classes = [MyThrottles,] def get(self, request):
return HttpResponse('get') def post(self, request):
return HttpResponse('post')
def throttled(self, request, wait):
from rest_framework.exceptions import Throttled
class MyThrottled(Throttled):
default_detail = '傻逼啊'
extra_detail_singular = '还有 {wait} second.'
extra_detail_plural = '出了 {wait} seconds.'
raise MyThrottled(wait)

3.2.2 限制匿名用户每分钟访问3次

REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m',
}
}
# 使用 `second`, `minute`, `hour` 或`day`来指明周期。
# 可以全局使用,局部使用

3.2.3 限制登陆用户每分钟访问10次

REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'user': '10/m'
}
}
# 可以全局使用,局部使用

3.2.4 其他

1) AnonRateThrottle

限制所有匿名未认证用户,使用IP区分用户。

使用DEFAULT_THROTTLE_RATES['anon'] 来设置频次

2)UserRateThrottle

限制认证用户,使用User id 来区分。

使用DEFAULT_THROTTLE_RATES['user'] 来设置频次

3)ScopedRateThrottle

限制用户对于每个视图的访问频次,使用ip或user id。

例如:

class ContactListView(APIView):
throttle_scope = 'contacts'
... class ContactDetailView(APIView):
throttle_scope = 'contacts'
... class UploadView(APIView):
throttle_scope = 'uploads'
...
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.ScopedRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'contacts': '1000/day',
'uploads': '20/day'
}
}

实例

全局配置中设置访问频率

'DEFAULT_THROTTLE_RATES': {
'anon': '3/minute',
'user': '10/minute'
}
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottle class StudentAPIView(RetrieveAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
throttle_classes = (UserRateThrottle,)

Django-rest-framework框架——路由组件、认证权限频率的更多相关文章

  1. Django Rest framework 框架之认证使用和源码执行流程

    用这个框架需要先安装: pip3 install djangorestframework 如果写了一个CBV的东西,继承了View. # 继承Django里面View class APIView(Vi ...

  2. Django REST framework框架介绍和基本使用

    Django REST framework介绍 Django REST framework是基于Django实现的一个RESTful风格API框架,能够帮助我们快速开发RESTful风格的API. 官 ...

  3. Django Rest Framework框架 ---- url控制器

    Django Rest Framework框架 ---- url控制器

  4. web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 ☝☝☝

    web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程    web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 学习 ...

  5. web前端Vue+Django rest framework 框架 生鲜电商项目实战✍✍✍

    web前端Vue+Django rest framework 框架 生鲜电商项目实战  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频 ...

  6. restful知识点之三restframework认证-->权限-->频率

    认证.权限.频率是层层递进的关系 权限业务时认证+权限 频率业务时:认证+权限+频率 局部认证方式 from django.conf.urls import url,include from djan ...

  7. 实战-DRF快速写接口(认证权限频率)

    实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...

  8. drf-day8——断点调试、认证.权限.频率的源码分析、基于APIView编写分页、全局异常处理

    目录 一.断点调试使用 二.认证,权限,频率源码分析(了解) 2.1 权限类的执行源码 2.2 认证源码分析 2.3 频率源码分析 2.4 自定义频率类(了解) 2.5 SimpleRateThrot ...

  9. 断点调试/认证/权限/频率-源码分析/基于APIView编写分页/异常处理

    内容概要 断点调试 认证/权限/频率-源码分析 基于APIView编写分页 异常处理 断点调试 # 程序以 debug模式运行,可以在任意位置停下,查看当前情况下变量数据的变化情况 # pycharm ...

  10. Django rest framework框架中有哪些组件

    认证 权限(授权) 用户访问次数/频率限制 版本 解析器(parser) 序列化 分页 路由系统 视图 渲染器 认证 自定义认证的类 """ from rest_fram ...

随机推荐

  1. Python Selenium UI自动化测试

    Python Selenium UI自动化测试 1.自动化测试基础 1.1 自动化测试的定义 将人为的测试行为转化为机器自动执行的过程 1.2 自动化测试的目的 减少成本,提高测试效率 减少人为因素对 ...

  2. 稳,从数据库连接池 testOnBorrow 看架构设计

    本文从 Commons DBCP testOnBorrow 的作用机制着手,管中窥豹,从一点去分析数据库连接池获取的过程以及架构分层设计. 以下内容会按照每层的作用,贯穿分析整个调用流程. 1️⃣框架 ...

  3. 文本识别分类系统python,基于深度学习的CNN卷积神经网络算法

    一.介绍 文本分类系统,使用Python作为主要开发语言,通过TensorFlow搭建CNN卷积神经网络对十余种不同种类的文本数据集进行训练,最后得到一个h5格式的本地模型文件,然后采用Django开 ...

  4. LLE算法在自然语言生成中的应用:实现文本到语音的情感迁移

    目录 自然语言生成(Natural Language Generation,NLP)是人工智能领域的一个分支,它利用大量的文本数据训练出语言模型,从而实现对自然语言的生成和理解.在NLP中,情感迁移( ...

  5. VSCode中打开NodeJS项目自动切换对应版本的配置

    这几年搞了不少静态站点,有的是Hexo的,有的是VuePress的.由于不同的主题对于NodeJS的版本要求不同,所以本机上不少NodeJS的版本. 关于如何管理多个NodeJS版本,很早之前就写过用 ...

  6. Nginx获取用户真实IP

    Nginx获取用户真实IP地址 本人在一次项目中,使用Nginx需要获取到用户IP,本来可以很常规的获取的,可现实往往不常规,项目是前后端分离的,部署时,前端使用了Nginx进行了代理并转发,后端也使 ...

  7. Mybatis(Map)

    Map 假设,我们的实体类,或者数据库中的表,字段或参数过多,我们应当考虑使用map 创建接口 //万能的mapper,我们不需要知道数据库里面有什么,是一个键值对的表现 //我们只需查询对应的字段 ...

  8. python添加水印

    # coding:utf-8 from PIL import Image, ImageDraw, ImageFont def add_text_to_image(image, text): font ...

  9. shell: xcall

    #!/bin/bash ips=( 1.1.1.2 1.1.1.1 ) port= user= passwd= for i in ${ips[@]} do echo "== $i ==&qu ...

  10. zabbix 概念 - 主机、主机配置模板

    zabbix 是以"主机"为单位来组织监控项的. 主机(Host)是一个你想要监控的网络实体(物理的,或者虚拟的).它可以是一台物理服务器,一个网络交换机,一个虚拟机或者一些应用. ...