昨日回顾

  • 认证类
#1  认证的使用
-有些接口需要登录后才能访问
-原生djagno如何使用的认证:auth的user表,auth自带了认证
-自己登录,使用自定义的用户表
-认证类的使用步骤:
-1 写一个类,继承BaseAuthentication
-2 重写 authenticate,在方法中完成认证,并且获取到当前登录用户,返回
-咱们代码从地址栏中取
-request.query_params.get('token')
-原生djagno,取出前端传入cookie,从哪取的?
request.COOKIE.get('sessionid')
-后期如果想从请求头中取
request.META.get('HTTP_TOKEN')
-如果认证通过,返回两个值,第一个是当前登录用户,第二个是token,或者返回None
-3 局部全局使用

原生django的认证,使用的是cookie这种机制。

三种位置的token获取

这个cookie是从哪里取的?

request.COOKIE.get('sessionid')

token认证:

从地址栏中取:request.query_params.get('token')

请求头中取: request.META.get('HTTP_TOKEN')

这里其实就是获取请求头中的token参数:

request.META.get('HTTP_参数')

如果token从cookie带过来,使用这种方法取:

request.COOKIE.get('sessionid')

注意: cookie也是在请求头。

认证类的返回值:

一个是当前登录用户,第二个是token,或者返回None。

三种权限校验方式

  • 权限类
# 2 权限的使用   

* ACL(访问控制列表)
如果有权限,就在权限列表里面。判断权限是不是在列表中
* rbac(基于角色的访问控制,公司内部系统)
* abac(rbac升级版,加了属性认证) 示例: 德邦使用的权限校验[Django-Vue-Admin] -return True或False
-中文提示 :self.message
-get_字段名_display()

Django-Vue-Admin

在action装饰器上加permission_classes参数.实现基于类方法的权限。

  • 频率类
# 3 频率
-写类继承SimpleRateThrottle
-重写get_cache_key,返回什么,就以什么做频率限制
-类属性:scope='名字'
-配合配置文件中:DEFAULT_THROTTLE_RATES
-局部和全局使用
  • 过滤类
# 4 过滤(查询所有才有过滤)
-内置的:模糊匹配
-第三方:精准匹配
-自定义过滤类
-filter_backends
  • 排序
# 5 排序
-内置排序即可

排序和游标分页不能一起用。因为游标分页需要指定一个字段进行排序。也就是说游标分页自带一个排序,一起用会冲突。

  • 分页
# 6 分页
-三种分页方式:重写三个类
-但是一个接口只能有一种分页类

5000万级别以上的项目,可以使用游标分页。

原生django的cookie+session认证底层原理

  • 原生django的认证:auth模块自带用户认证,django提供user表
  • drf 的认证: 使用自定义的用户表 使用认证类

request.session['name']=lqz的本质:

  1. 生成随机字符串
  2. 把数据(key:value)写人django-session表中
  3. 把随机字符串当cookie的value值返回给前端浏览器

    sessionid = 随机字符串

上一次是旧的request对象,这次是新的request对象。有一个session的中间件,会取出cookie对应的随机字符串,去数据库中根据随机字符串查询。把查回来的数据(字典),转到request.session对象中。

如果使用了auth模块。auth.login()这内部就在做如上操作。

浏览器功能:

只要是向当前域发送请求,会自动携带cookie放到请求头中。

查看中间件:

中间件是配合默认的app使用的:



这些app和中间件都可以不使用。

中间件获取cookies:

默认设置给浏览器的cookies的key的名字为sessionid,这是一个默认配置,在配置文件中写了(可以自己在settings里面改):

去数据库,查询session,并将session数据存放在request.session对象中:(这个类实例化的时候,就会去做这件事)

session存储的位置默认放在session表.还可以放在缓存数据库\文件中.

断点调试使用

# 程序是 debug模式运行,可以在任意位置停下,查看当前情况下变量数据的变化情况

# pycharm 来调试程序
-以debug形式运行
-在左侧空白处,点击加入断电 (红圈)
-step over 单步调试
-step into 进入到函数内部运行
-快速调到下一个断电,绿色箭头

pycharm调试程序:

  1. debug模式运行

  2. wsgi -- 中间件 -- 路由匹配 -- as_view - 三大认证 - 执行视图函数方法

  • step_over执行下一行
  • step_into执行里面

快速跳到下一个断点:

9.39

认证,权限,频率源码分析(了解)

权限源码分析

# 权限的源码执行流程
-写一个权限类,局部使用,配置在视图类的,就会执行权限类的has_permission方法,完成权限校验 # 之前读过:drf的apiview,在执行视图类的方法之前,执行了3大认证----》dispatch方法中的
-497行左右, self.initial(request, *args, **kwargs)---》执行3大认证 # APIView类的399行左右:
def initial(self, request, *args, **kwargs):
# 能够解析的编码,版本控制。。。。
self.format_kwarg = self.get_format_suffix(**kwargs)
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme # 认证组件的执行位置
self.perform_authentication(request)
# 权限组件 [读它]
self.check_permissions(request)
# 频率组件
self.check_throttles(request) # APIView的326 左右
def check_permissions(self, request):
# self.get_permissions()----》[CommonPermission(),]
# permission 是我们配置在视图类上权限类的对象
for permission in self.get_permissions():
# 权限类的对象,执行has_permission,这就是为什么我们写的权限类要重写has_permission方法
# self 是视图类的对象,就是咱们自己的的权限类的has_permission的view参数
if not permission.has_permission(request, self):
# 如果return 的是False,就会走这里,走这里是,没有权限
# 如果配了多个权限类,第一个没过,直接不会再执行下一个权限类了
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
) # APIView的274行左右 get_permissions
def get_permissions(self):
# self.permission_classes 是咱们配置在视图类上的列表,里面是一个个的权限类,没加括号
# permission_classes = [CommonPermission]
# [CommonPermission(),] 本质返回了权限类的对象,放到列表中
return [permission() for permission in self.permission_classes] # 总结:
-APIView---dispatch----》initial---》倒数第二行---》self.check_permissions(request)
里面取出配置在视图类上的权限类,实例化得到对象,一个个执行对象的has_permission方法,如果返回False,就直接结束,不再继续往下执行,权限就认证通过 -如果视图类上不配做权限类:permission_classes = [CommonPermission],会使用配置文件的api_settings.DEFAULT_PERMISSION_CLASSES
优先使用项目配置文件,其次使用drf内置配置文件

前期准备:

问什么在类属性上配置了权限类,就会生效?

入口:APIView dispatch中的三大认证:

APIView的 check_permissions:

self.get_permissions APIView的274行:

self.permission_class: 也就是我们配置的权限类

返回出去的是 ,你写的权限类的对象,每个权限类都产生一个对象,每个对象都放在列表中

回去:



取出对象。

对象调用has_permission。

请注意传入的self(APIView对象)对应权限类has_permission的view参数。

如果return false:

self.permission_denied:

如果配置了多个权限类,第一个没过就不会执行下一个权限类了。

总结:

如果视图类中不配置权限类,会自动使用配置文件的权限,这是如何实现的?

优先使用项目配置文件 ---> DRF 产生对象

默认的 ---drf配置文件

字典的一个替换。

都使用的是default_permession_class 实际上是一个字典的替换。

认证源码分析

# 之前读过:drf的apiview,在执行视图类的方法之前,执行了3大认证----》dispatch方法中的
-497行左右, self.initial(request, *args, **kwargs)---》执行3大认证 # APIView类的399行左右:
def initial(self, request, *args, **kwargs):
# 能够解析的编码,版本控制。。。。
self.format_kwarg = self.get_format_suffix(**kwargs)
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme # 认证组件的执行位置【读它】
self.perform_authentication(request)
# 权限组件
self.check_permissions(request)
# 频率组件
self.check_throttles(request) # APIView的316行左右
def perform_authentication(self, request):
request.user #咱们觉得它是个属性,其实它是个方法,包装成了数据属性 # Request类的user方法 219行左右
@property
def user(self):
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user # self 是Request的对象,找Request类的self._authenticate() 373 行
def _authenticate(self):
# self.authenticators 我们配置在视图类上认证类的一个个对象,放到列表中
# Request类初始化的时候,传入的
for authenticator in self.authenticators:
try:
# 返回了两个值,第一个是当前登录用户,第二个的token,只走这一个认证类,后面的不再走了
# 可以返回None,会继续执行下一个认证类
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise if user_auth_tuple is not None:
self._authenticator = authenticator
# 解压赋值:
#self.user=当前登录用户,self是当次请求的新的Request的对象
#self.auth=token
self.user, self.auth = user_auth_tuple
return self._not_authenticated() # self.authenticators 去Request类的init中找 152行左右
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
.....
self.authenticators = authenticators or ()
..... # 什么时候调用Reqeust的__init__?---》APIVIew的dispatch上面的492行的:request = self.initialize_request(request, *args, **kwargs)-----》385行----》
def initialize_request(self, request, *args, **kwargs):
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
) # 总结:
1 配置在视图类上的认证类,会在执行视图类方法之前执行,在权限认证之前执行
2 自己写的认证类,可以返回两个值或None
3 后续可以从request.user 取出当前登录用户(前提是你要在认证类中返回)

APIView的316:

request.user 看起来是属性,其实是方法包装成了数据属性。

Request类的User方法 219:

执行self._authenticate self是request,所以在request类中找:

依据之前的权限我们猜测:

self.authenticators request初始化传入 152:

什么时候调用Request的__init__

回到APIView的dispatch 492:



385:

会调用get_authenticators:

跟我们猜的一样。

类 方法 request

AuthenticationFiead继承了APIexception

三大认证都可以抛出APIException。



可以返回两个值也可以返回一个。

如果返回None会继续指向下一个认证类。

先执行三大认证才执行视图类中的方法。

如果写了多个认证类,前面的必须return false 最后一个认证类必须返回两个值.

认证类返回两个值,表示到认证到此结束。

返回一个None.表示这个认证类执行完后,继续下一个认证

这里将request.user里面存入了当前用户。

频率源码分析

# 之前读过:drf的apiview,在执行视图类的方法之前,执行了3大认证----》dispatch方法中的
-497行左右, self.initial(request, *args, **kwargs)---》执行3大认证 # APIView类的399行左右:
def initial(self, request, *args, **kwargs):
# 能够解析的编码,版本控制。。。。
self.format_kwarg = self.get_format_suffix(**kwargs)
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme # 认证组件的执行位置
self.perform_authentication(request)
# 权限组件
self.check_permissions(request)
# 频率组件【读它】
self.check_throttles(request) # APIView 的352行
def check_throttles(self, request):
throttle_durations = []
#self.get_throttles() 配置在视图类上的频率类的对象,放到列表中
# 每次取出一个频率类的对象,执行allow_request方法,如果是False,频率超了,不能再走了
# 如果是True,没有超频率,可以直接往后
for throttle in self.get_throttles():
if not throttle.allow_request(request, self):
throttle_durations.append(throttle.wait()) if throttle_durations:
# Filter out `None` values which may happen in case of config / rate
# changes, see #1438
durations = [
duration for duration in throttle_durations
if duration is not None
] duration = max(durations, default=None)
self.throttled(request, duration) # 总结:
-我们写的频率类:继承BaseThrottle,重写allow_request,在内部判断,如果超频了,就返回False,如果没超频率,就返回True

APIView的352行:

也是产生我们频率类的对象。

三大认证中的频率是根据allow_request方法的返回值来判断是否频率超了

关于这个allow_request: simple帮写了base没写。

自定义频率类(了解)

我们写的频率类:

如果继承了BaseThorttle,就需要重写allow_request。

如果继承了SimpleRateThrottle, SimpleRateThrottle帮写了allow_request(),我们只需要写get_cache_key().

后期加频率需要手写,可以记住这个频率控制逻辑,写在中间件。

任意语言,任意框架限制频率都是这个逻辑:

代码实现:

class SuperThrottle(BaseThrottle):
VISIT_RECORD = {} def __init__(self):
self.history = None def allow_request(self, request, view):
# 自己写逻辑,判断是否超频
# (1)取出访问者ip
# (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走 {ip地址:[时间1,时间2,时间3,时间4]}
# (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
# (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
# (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
# (1)取出访问者ip
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 = [时间1]
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])

显示还剩多长时间解除限流,如何实现?

再重写一个wait函数,wait函数的返回值就是返回剩余的时间:

# 频率类,不继承BaseThrottle,继承SimpleRateThrottle,少写代码
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
import time '''示例''' class CommonThrottle(SimpleRateThrottle):
# 类属性,属性值随便写
# 配置文件中配置
scope = 'lqz' def get_cache_key(self, request, view):
# 返回什么,就以什么做频率限制【可以返回ip 或用户ID】
# 客户端的ip地址从哪里拿?
return request.META.get('REMOTE_ADDR') # 以ip做限制
# return request.user.pk # 以用户id做限制 '''我写的''' class AllApiThrottle(SimpleRateThrottle): ## 实现所有接口限流 10/m
scope = 'all_api' def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR') '''再写一个限流''' class SuperThrottle(BaseThrottle):
visit_dict = {}
wait_time = None
timer = time.time def __init__(self):
self.history = None def allow_request(self, request, view): request_ip = request.META.get('REMOTE_ADDR')
# 如果ip不在访问字典里面
if request_ip not in self.visit_dict:
# 添加这个ip到访问字典
self.visit_dict[request_ip] = []
# 添加当前时间到列表 {'127.0.0.1': [1675772107.80177]}
self.visit_dict[request_ip].append(self.timer()) return True
# 如果ip在字典里面 ---> 说明是第二次来
else:
# 先把时间列表取出来:
time_list = self.visit_dict.get(request_ip)
print(time_list)
# 如果列表里有值,但是列表肯定有值啊
if time_list:
end_time = time_list[-1]
self.history = 60 - abs(end_time - self.timer()) # 神奇的写法!
if (self.timer() - end_time) >= 60:
time_list.remove(end_time)
if len(time_list) < 5:
time_list.insert(0, self.timer())
return True
else:
return False def wait(self): # 这个类的对象会调用这个方法
print(self.history, 2)
return self.history

SimpleRateThrottle缓存频率类

# 写一个频率类,重写allow_request方法,在里面实现频率控制

# SimpleRateThrottle---》allow_request
def allow_request(self, request, view):
# 这里就是通过配置文件和scop取出 频率限制是多少,比如一分钟访问5此
if self.rate is None:
return True # 返回了ip,就以ip做限制
self.key = self.get_cache_key(request, view)
if self.key is None:
return True
# 下面的逻辑,跟咱们写的一样
self.history = self.cache.get(self.key, [])
self.now = self.timer()
while self.history and self.history[-1] <= self.now - self.duration:
self.history.pop()
if len(self.history) >= self.num_requests:
return self.throttle_failure()
return self.throttle_success() # SimpleRateThrottle的init方法
def __init__(self):
if not getattr(self, 'rate', None):
# self.rate= '5、h'
self.rate = self.get_rate()
# 5 36000
self.num_requests, self.duration = self.parse_rate(self.rate)
# SimpleRateThrottle的get_rate() 方法
def get_rate(self): if not getattr(self, 'scope', None):
msg = ("You must set either `.scope` or `.rate` for '%s' throttle" %
self.__class__.__name__)
raise ImproperlyConfigured(msg) try:
# self.scope 是 lqz 字符串
# return '5/h'
return self.THROTTLE_RATES[self.scope]
except KeyError:
msg = "No default throttle rate set for '%s' scope" % self.scope
raise ImproperlyConfigured(msg) # SimpleRateThrottle的parse_rate 方法
def parse_rate(self, rate):
# '5/h'
if rate is None:
return (None, None)
# num =5
# period= 'hour'
num, period = rate.split('/')
# num_requests=5
num_requests = int(num)
duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]
# (5,36000)
return (num_requests, duration)

看看人家怎么写:

初始化获取类中rate属性,如果没有rate属性就执行get_rate()

如果不设置scope属性会报错:

我们时放在字典,列表中,他是放在缓存中了:

放在缓存的好处》》可以放在别的数据库中。

取当前时间:没加括号的类属性

什么时候用,什么时候加括号:

可以添加日志功能:

小米:

时间序列数据库.

实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法。也就是说类产生的所有对象,都是共用类属性的。

基于APIView编写分页

# 分页功能,只有查询所有才有

class BookView(ViewSetMixin, APIView):
def list(self, request):
books = Book.objects.all()
# 使用步骤
# 1 实例化得到一个分页类的对象
paginator = CommonLimitOffsetPagination()
# 2 调用分页类对象的paginate_queryset方法来完成分页,返回的page是 要序列化的数据,分页好的
page = paginator.paginate_queryset(books, request, self)
if page is not None:
serializer = BookSerializer(instance=page, many=True)
# 3 返回数据,调用paginator的get_paginated_response方法
# return paginator.get_paginated_response(serializer.data)
return Response({
'total': paginator.count,
'next': paginator.get_next_link(),
'previous': paginator.get_previous_link(),
'results': serializer.data
})

分页功能只有查询所有接口才有。

from rest_framework.views import APIView

如果重写,需要自己映射路由。

list添加装饰器会出问题,可以使用原生django提供的装饰器,或者使用action装饰器 。

由于我们将get映射为list,所以需要重写list:

直接复制GenericAPIView中的list方法,学习GenericAPIView源码来写APIView:

需要在GenericAPIView找paginate_queryset:

可以发现需要一个分页类的对象paginater.这个分页器对象再调用父类的paginate_queryset,在这里真正的实现分页.

直接Response有小问题:

这个实现了next下一页上一页功能:

实际上:

'''基于APIView编写分页'''
class BookView(ViewSetMixin, APIView): # 请求来之后经过魔法类的as_view 会进行方法的映射 self.get = self.list 存放了父类的self.list def list(self, request, *args, **kwargs):
books = Book.objects.all()
# 使用步骤
# 1. 实例化得到一个分页类的对象
paginator = CommonLimitOffsetPagination()
# 2. 调用paginator对象的方法
page = paginator.paginate_queryset(books, request, view=self) # returning a page object, or `None`
if page is not None:
serializer = BookSerializer(instance=page, many=True) return Response({
'count': paginator.count,
'next': paginator.get_next_link(),
'previous': paginator.get_previous_link(),
'results': serializer.data
}) # '''示例'''
# # def list(self, request, *args, **kwargs):
# # queryset = self.filter_queryset(self.get_queryset())
# #
# # page = self.paginate_queryset(queryset)
# # if page is not None:
# # serializer = self.get_serializer(page, many=True)
# # return self.get_paginated_response(serializer.data)
# #
# # serializer = self.get_serializer(queryset, many=True)
# # return Response(serializer.data)

异常处理

# APIView--->dispatch--->三大认证,视图类的方法,如果出了一场,会被一场捕获,捕获后统一处理
# drf 内置了一个函数,只要上面过程出了异常,就会执行这个函数,这个函数只处理的drf的异常
-主动抛的非drf异常
-程序出错了
都不会被处理
我们的目标,无论主动抛还是程序运行出错,都同意返回规定格式--》能记录日志
公司里一般返回 {code:999,'msg':'系统错误,请联系系统管理员'} # 写一个函数,内部处理异常,在配置文件中配置一下即可 def common_exception_handler(exc, context):
# exc 错误对象
# context:上下文,有view:当前出错的视图类的对象,args和kwargs视图类方法分组出来的参数,request:当次请求的request对象
# 只要走到这里,就要记录日志 ,只有错了,才会执行这个函数
# 记录日志尽量详细
print('时间,登录用户id,用户ip,请求方式,请求地址,执行的视图类,错误原因')
res = exception_handler(exc, context)
if res: # 有值,说明返回了Response 对象,没有值说明返回None
# 如果是Response 对象说明是drf的异常,已经被处理了,如果是None表明没有处理,就是非drf的异常
res = Response(data={'code': 888, 'msg': res.data.get('detail', '请联系系统管理员')})
else:
# res = Response(data={'code': 999, 'msg': str(exc)})
# 记录日志
res = Response(data={'code': 999, 'msg': '系统错误,请联系系统管理员'}) return res # 在配置文件中配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.exceptions.common_exception_handler',
}

exc错误对象:

这个函数只处理drf的异常:

drf的异常继承了API异常,drf的异常会被处理 所有前端返回字典。

普通异常:

drf的异常会捕获。

我们的目的 ---> 普通异常也进行捕获 ---> 记录日志 ---> 前端返回固定格式

公司返回的固定格式:

{code:999,'msg':'xxxx'}

自己写异常捕获:

看看人家写的:

看看配置成功没:

drf的异常时888 普通异常为999 res.data是哪里来的 。

exc是错误对象。context上下文 ---> 字典 view对象

只要执行我们这个捕获报错的函数,就要记录日志。

从request中拿,没有request就匿名用户。

import time

from rest_framework.views import exception_handler  # 这个是drf默认的异常管理器
from rest_framework.response import Response from .models import User def common_exceptions_handler(exc, context):
request = context.get('request')
print('----------------------------------')
print('时间:', time.strftime('%Y-%M-%d %X'))
token = request.query_params.get('token')
if token:
user_id = User.objects.filter(usertoken__token=token).first().id
print('用户id:', user_id)
print('请求地址:', str(request))
print('用户ip:', request.META.get('REMOTE_ADDR'))
print('请求方式:', request.method)
print('执行的视图类:', str(context.get('view')))
print('错误信息:', exc) res = exception_handler(exc, context)
if res:
res = Response(data={'code': 888, 'msg': res.data.get('detail')})
else:
res = Response(data={'code': 666, 'msg': '系统错误, 请联系管理员'})
return res

认证,权限,频率源码分析 自定义频率类 SimpleRateThrottle缓存频率类 基于APIView编写分页的更多相关文章

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

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

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

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

  3. Django框架之drf:8、断点调试,权限、认证、频率组件源码分析,基于APIView编写分页,异常处理

    Django框架之drf 一.断点调式使用 ​ 指,在我们编写代码的时候,程序运行出现报错是无可避免的,当程序 出现报错时,我们需要找到出现报错的代码进行修改,如果时简短的代码很容易就可以找到报错位置 ...

  4. drf-三大认证源码分析、基于APIView编写分页、异常处理

    1.权限源码分析 1.APIView源码497行:self.initial(request, *args, **kwargs)中进行了三大认证. 2.在initial的源码中,以下三行代码是进行三大认 ...

  5. Django(63)drf权限源码分析与自定义权限

    前言 上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf默认是允许所有用户访问 权限源码分析 源码入口:APIView.py文件下的initial方法下的check_per ...

  6. Django-restframework 之频率源码分析

    Django-restframework 之频率源码分析 一 前言 经过权限判断之后就是进行频率的判断了,而频率的判断和权限又不一样,认证.权限和频率的执行流程都差不多,使用配置里面的相关类来进行判断 ...

  7. Django-restframework 之权限源码分析

    Django-restframework 之权限源码分析 一 前言 上篇博客分析了 restframework 框架的认证组件的执行了流程并自定义了认证类.这篇博客分析 restframework 的 ...

  8. Django-restframework 源码之认证组件源码分析

    Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...

  9. DRF的认证组件(源码分析)

    DRF认证组件(源码分析) 1. 数据库建立用户表 在drf中也给我们提供了 认证组件 ,帮助我们快速实现认证相关的功能,例如: # models.py from django.db import m ...

  10. Django REST framework —— 认证组件源码分析

    我在前面的博客里已经讲过了,我们一般编写API的时候用的方式 class CoursesView(ViewSetMixin,APIView): pass 这种方式的有点是,灵活性比较大,可以根据自己的 ...

随机推荐

  1. [MDP.NetCore] 使用AzureAD+服務主體,快速建立兩個服務之間的Service身分認證

    MDP.AspNetCore.Authentication.AzureAD.Services for Service Principal MDP.AspNetCore.Authentication.A ...

  2. Android Recyclerview的item间距实现

    Recyclerview中,提供了一个方法addItemDecoration给我们用于设置item的分割线 下面提供几个常见的分割线效果 注: 下面的SizeUtils是AndroidUtilCode ...

  3. python之史上最详细if教程

    目录 简单的if语句 关系运算符 if-else语句 if-elif-else语句 使用多个elif代码块 省略else代码块 测试多个if 简单的if语句 if语句,顾名思义就是如果...那么就.. ...

  4. 23C新特性:True Cache的介绍

    我们的文章会在微信公众号"Oracle恢复实录"和博客网站"https://www.cnblogs.com/www-htz-pw/" 同步更新 ,欢迎关注收藏, ...

  5. StackGres 1.6 数据库平台工程功能介绍以及快速上手

    StackGres 1.6 数据库平台工程功能 声明式 K8S CRs StackGres operator 完全由 Kubernetes 自定义资源管理.除了 kubectl 或任何其他 Kuber ...

  6. 神经网络优化篇:详解偏差,方差(Bias /Variance)

    偏差,方差 注意到,几乎所有机器学习从业人员都期望深刻理解偏差和方差,这两个概念易学难精,即使自己认为已经理解了偏差和方差的基本概念,却总有一些意想不到的新东西出现.关于深度学习的误差问题,另一个趋势 ...

  7. [USACO2007NOVS] Milking Time S

    题目描述 Bessie 可以在接下来 \(N\) 个小时内产奶,为了方便,我们把这 \(N\) 个小时 \(0\dots N-1\) 编号. FJ 在这 \(N\) 个小时内有 \(M\) 段时间可以 ...

  8. [ABC265B] Explore

    Problem Statement Takahashi is exploring a cave in a video game. The cave consists of $N$ rooms arra ...

  9. 通过 VS Code 优雅地编辑 Pod 内的代码(非 NodePort)

    目录 1. 概述 2. NodePort 方式 3. Ingress 方式 4. 救命稻草 5. 其他 1. 概述 今天聊点啥呢,话说,你有没有想过怎样用 VS Code 连上 K8s 集群内的某个 ...

  10. linux 上安装kapacitor

    转载请注明出处: 1.通过安装包安装 1.使用以下命令下载安装包: wget https://dl.influxdata.com/kapacitor/releases/kapacitor_1.6.3- ...