昨日回顾

  • 认证类
#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. promise时效架构升级方案的实施及落地

    一.项目背景 为什么需要架构升级 promise时效包含两个子系统:内核时效计算系统(系统核心是时效计算)和组件化时效系统(系统核心是复杂业务处理以及多种时效业务聚合,承接结算下单黄金流程流量),后者 ...

  2. “技能兴鲁”职业技能大赛-网络安全赛项-学生组初赛 Crypto WP

    babyRSA 查看代码 from gmpy2 import * from Crypto.Util.number import * flag = 'flag{I\'m not gonna tell y ...

  3. JavaScript Date转字符串格式

    JavaScript Date转字符串格式

  4. 七天.NET 8操作SQLite入门到实战 - SQLite 简介

    什么是SQLite? SQLite是一个轻量级的嵌入式关系型数据库,它以一个小型的C语言库的形式存在.它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可 ...

  5. 领域驱动设计之银行转账:Wow框架实战

    银行账户转账案例 银行账户转账案例是一个经典的领域驱动设计(DDD)应用场景.接下来我们通过一个简单的银行账户转账案例,来了解如何使用 Wow 进行领域驱动设计以及服务开发. 银行转账流程 准备转账( ...

  6. 基于Python下MySQL数据库驱动

    由于MySQL服务器以独立的进程运行,并通过网络对外服务,所以,需要支持Python的MySQL驱动来连接到MySQL服务器. 1.mysql-connector-python ​ mysql-con ...

  7. iOS信号量造成线程优先级反转

    在并发队列使用信号量会可能会造成线程优先级反转 一.在iOS16 & XCode14上遇到 - 使用信号量造成线程优先级反转问题 提醒 经过查询资料,发现是在XCode14上增加了工具,比如 ...

  8. 🔥🔥Java开发者的Python快速进修指南:网络编程及并发编程

    今天我们将对网络编程和多线程技术进行讲解,这两者的原理大家都已经了解了,因此我们主要关注的是它们的写法区别.虽然这些区别并不是非常明显,但我们之所以将网络编程和多线程一起讲解,是因为在学习Java的s ...

  9. 全面的.NET微信网页开发之JS-SDK使用步骤、配置信息和接口请求签名生成详解

    JSSDK使用步骤 步骤一:绑定安全域名: 先登录微信公众平台进入"公众号设置"的"功能设置"里填写"JS接口安全域名". 步骤二:引入JS ...

  10. Scrapyd、scrapyd-client部署爬虫项目

    命令参考:https://github.com/scrapy/scrapyd-client https://scrapyd.readthedocs.io 安装组件 pip install scrapy ...