1.restful规范

resfful规范的概念最重要:
  是一套规范,规则,用于程序之间进行数据交换的约定。
  他规定了一些协议,对我们感受最直接的就是,以前写增删改查的时候需要些四个视图寒素,restful规范写一个接口,根据http协议的请求方式分为不同的操作,比如post,get,put,patch,delete.
  除此之外restful规范还规定了:

1.建议用https协议代替http协议
2.在url中要体现pai,添加api标识(体现出我写的是api)
http://www.baidu.com/api(推荐使用这种,因为不需要跨域)
http://api.baidu.com/(可能出现跨域问题)
3.url中要体现出版本
http://www.baidu.com/api/v1/xxxx
也可以放在请求头里面(content-type)
4.一般情况下对于api接口,用名词不适用动词
http://www.baidu.com/api/v1/userinfo
5.如果有条件的话在url后面进行传递
http://www.baidu.com/api/v1/userinfo/page=1&category=1 6.根据method不同做不同的操作
get/post/put/patch/delete    7.数据之间一般通过json来传递
   8.-url 一般用名词 http://www.baidu.com/article/(面向资源变成,网上所有的数据都是资源)
   9.根据请求方式的不同去做不同的操作:get,post,put,delete,patch
   10.根据筛选条件可以在url后面添加参数:http://www.baidu.com/article?page=1&categroy=1
      注意筛选条件都放在url中进行传递


   从url开始记器,会比较好记

 2.简述drf类的继承关系

简述drf类的继承关系
apiview和view里面都有dispatch方法
apiview里面的dispatch会根据请求方式的不同执行反射
initial()是执行视图函数之前来执行 class View(object):
def dipatch(self):
print(123) class APIView(View):
version_class = settings.xxx
parser_class = settings.sxx
permision_classes = [] def dipatch(self): self.initial() method = getattr(self,"get")
return method() def initial(self):
self.version_class()
self.parser_class()
for item in self.permision_classes:
item() class GenericAPIView(APIView):
queryset = None
serilizer_class = None
def get_queryset(self):
return self.queryset def get_serilizer(self,*arg,**kwargs):
cls = self.get_serilizer_class()
return cls(*arg,**kwargs) def get_serilizer_class(self):
return self.serilizer_class class ListModelMixin(object):
def list(self):
queryset = self.get_queryset()
ser = self.get_serilizer(queryset,many=True)
return Reponse(ser.data) class ListAPIView(ListModelMixin,GenericAPIView):
def get(self):
return self.list(...) class TagView(ListAPIView):
queryset = models.User.object.all()
serilizer_class = TagSerilizer
version_class = URLPathClass
parser_class = JSONParser
permission_classes = [Foo,Bar ] obj = TagView()
x = obj.dispatch()
给用户返回x 1.drf所有的功能都是从dispatch方法衍生过来的
apiview提供了大量的公共组件,但是gennerview提供了基于公共的帮助我们进行增删改查
apiview:
1.请求的封装
获取请求体:request.data
获取url上参数:request.query+params()
注意:drf的request和原本的requests是不一样的,一定记住执行视图函数之前执行initial

3.drf请求封装(request请求的封装)

    class HttpRequest(object):
def __init__(self):
pass @propery # 方法变成属性
def GET(self):
pass @propery
def POST(self):
pass @propery
def body(self):
pass class Request(object):
def __init__(self,request):
self._request = request def data(self):
# 里面与解析器有关
if content-type == "application/json"
reutrn json.loads(self._request.body.decode('urf-8'))
elif content-type == "x-www-...":
return self._request.POST def query_params(self):
return self._reqeust.GET req = HttpRequest() # 相当于django的request
request = Request(req) # 相当于drf中的request
# drf将django的request 封装到自己的request中
request.data
request.query_prams
request._request.GET
request._request.POST
request._request.body

重点:
在dispatch里面的request = self.initialize_request(request, *args, **kwargs)是在进行request对象的封装
其中initialize_request方法返回了如下:不仅封装了老的request,还封装了一些其他属性的值
return Request(
request, # 封装了老的request
parsers=self.get_parsers(),
authenticators=self.get_authenticators(), # 封装了需要认证的初始化类,是一个对象列表
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)

4.drf源码分析view(drf里面的请求流程)

drf源码分析view(drf里面的请求流程)
重点:请求进行必须去找dispatch drf入口请求的流程
1.从url开始分析
urlpatterns = {
url(r'^order/$', views.OrderView.as_view()), # 会返回一个函数,csrf_exemt(view)
} 2.视图关系
class View(object):
@classonlymethod
def as_view(cls, **initkwargs): # django的as_view方法
def view(request, *args, **kwargs):
return self.dispatch(request, *args, **kwargs)
return view class APIView(View): @classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs) #调用父类的as_view方法
return csrf_exempt(view)
def dispatch(self, request, *args, **kwargs):
# 新request内部包含老request(_reuqest=老request)
request = self.initialize_request(request, *args, **kwargs)
self.request = request self.initial(request, *args, **kwargs) # 通过反射执行“get”方法,并传入新的request
handler = getattr(self, request.method.lower())
response = handler(request, *args, **kwargs) # get(requst)
return self.response class OrderView(APIView): def get(self,request,*args,**kwargs):
return Response('海狗') 3.fbv和cbv的本质都是执行函数 请求没有到来时(django初始化时):
1.知道路由,执行as_view方法
2.由于继承的是apiview的类,并且里面有as_view方法,就执行apiview里面的as_view方法
3.由于apiview里面的as_view执行父类里面的view方法,因为apiview继承的是django的view,所以执行django的as_view方法
4.django的as_view返回的是其本身的view函数的内存地址
5.所以apiview里面的as_view方法返回的是:django的as_view里面的view函数的内存地址,并加上了免除csrf认证 请求到来时(get/post等方法):
1.由于路由里面的as_view加扩号了,所以请求到来时,会自动执行as_view方法
并且在初始化时,url里面as_view等于的是免除csrf认证的django的as_view里面的view方法的内存地址
所以相当于执行django的as_view里面的view函数 2.其中view返回的是self.dispatch,会执行apiview里面的dispatch方法
3.apiview里面的dispatch方法主要做了三件事情
3.1 将老request变成新的request request = self.initialize_request(request, *args, **kwargs)
3.2 在视图函数之前执行initial方法
3.3 通过反射来找到request.method.lower()传递进来的方法
3.4 执行找到的传递进来的方法,如果是get的话,会执行OrderView里面的get方法
3.5 将return self.response返回值给django的as_view方法
3.6 django的view里面的返回值,返回给用户(是OrderView里面的get的返回值) 所以通过drf的请求流程我们知道知识点是:
1.fbv和cbv的本质都是一样的,都是执行函数
2.drf的请求认证返回的帮助我们做了一个csrf的认证 需要注意的是:
新的requets里面包含了老的request,并且传入到了视图函数里面 dispatch方法分析:
1.request是django的request,他的内部有request.GET requets.POST requets.method方法
args和kwargs是通过路由匹配过来的参数: url(r'^order/(\d+)/(?P<version>\w+)/$', views.OrderView.as_view()),
http://www.baidu.com/2018/v2
args:存放的是不带关键字的参数:2018
kwargs:存放的是带关键的参数:version=v2
其中的self是相当于我们本身请求的当对象 2.request = self.initialize_request(request, *args, **kwargs)
是将老的requet对象变成一个新的request,里面封装了一些值,里面包含老的request,并将新的requets返回给调用对象的reuqest self.query_params = request(老的request).GET
self.request.data = request.POST 3.需要记住的,request对象里面封装了request参数

  

5.版本控制及源码分析

版本控制及源码分析
from django.conf.urls import url,include
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^order/$', views.OrderView.as_view()),
] from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request class OrderView(APIView):
def get(self,request,*args,**kwargs):
print(request.version) # 等于版本控制的版本号
print(request.versioning_scheme) # 等于版本控制类的对象,也就是URLPathVersioning对象
return Response('...') def post(self,request,*args,**kwargs):
return Response('post') # 源码流程
class APIView(View):
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS def dispatch(self, request, *args, **kwargs): # ###################### 第一步 ###########################
"""
request,是django的request,它的内部有:request.GET/request.POST/request.method
args,kwargs是在路由中匹配到的参数,如:
url(r'^order/(\d+)/(?P<version>\w+)/$', views.OrderView.as_view()),
http://www.xxx.com/order/1/v2/
"""
self.args = args
self.kwargs = kwargs """
request = 生成了一个新的request对象,此对象的内部封装了一些值。
request = Request(request)
- 内部封装了 _request = 老的request
"""
request = self.initialize_request(request, *args, **kwargs)
self.request = request self.headers = self.default_response_headers # deprecate? try:
# ###################### 第二步 ###########################
self.initial(request, *args, **kwargs) 执行视图函数。。 def initial(self, request, *args, **kwargs): # ############### 2.1 处理drf的版本 ##############
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
... def determine_version(self, request, *args, **kwargs):
if self.versioning_class is None:
return (None, None)
scheme = self.versioning_class() # obj = XXXXXXXXXXXX()
return (scheme.determine_version(request, *args, **kwargs), scheme) class OrderView(APIView):
versioning_class = URLPathVersioning # 代表版本控制的类
def get(self,request,*args,**kwargs):
print(request.version)
print(request.versioning_scheme)
return Response('...') def post(self,request,*args,**kwargs):
return Response('post') from rest_framework.versioning import URLPathVersioning
# 用于实现版本控制的类代码
class URLPathVersioning(BaseVersioning):
"""
urlpatterns = [
url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'), ]
"""
invalid_version_message = _('Invalid version in URL path.') def determine_version(self, request, *args, **kwargs):
version = kwargs.get(self.version_param, self.default_version)
if version is None:
version = self.default_version if not self.is_allowed_version(version):
raise exceptions.NotFound(self.invalid_version_message)
return version 1.请求进来还会先执行dispatch方法,执行的时apiview里面的dispatch方法
2.执行视图函数之前执行了一个self.initial(request, *args, **kwargs),先在实例化执行的类中找initial方法
因为self里面没有,所以执行父类(apiview)里面的initial方法(注意initial执行在视图函数之前)
3.其中initial中执行的两句代码是处理drf的版本
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# version等于版本号
# scheme等于版本控制类的对象,也就是URLPathVersioning对象 4.其中determine_version执行的是apiview里面的determine_version
5.determine_version中执行了self.versioning_class类,其中获取self.versioning_class的两种方法:
5.1 在实例化中获取
5.2 在父类里面找(其中父类里面的versioning_class是在配置文件里面找的)
5.3 如果找不到的话,就为None
5.4 如果在父类或者配置文件中指定了版本类的话,就可以返回版本号和版本控制类的对象,也就是URLPathVersioning对象 6.因为能drf里面接受参数的方式有很多,所以我们自己写的类也可以继承多个版本控制类
GET /something/?version=0.1 HTTP/1.1 ---》QueryParameterVersioning,在QueryParameterVersioning里面是通过url后面的参数来取版本号 request.query_params.ge
GET /1.0/something/ HTTP/1.1----》URLPathVersioning (restful推荐使用该方式,因为符合restful的规范)在URLPathVersioning里面是通过kwagrs里面的值去取版本号。kwargs.get
URLPathVersioning方式的路由匹配规则
urlpatterns = [
url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'),
url(r'^(?P<version>[v1|v2]+)/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail')
url(r'^api/(?P<version>\w+)/', include('kka.urls')),
]
在URLPathVersioning里面是通过kwagrs里面的值去取版本号。 7.is_allowed_version
在配置文件那可以定义ALLOWED_VERSIONS来制定符合条件的版本号
REST_FRAMEWORK = {
"ALLOWED_VERSIONS":['V1','V2']
"VERSION_PARAM":"v"
}
8.VERSION_PARAM
告诉后端在url上取值的是根据什么取值的,在设定的里面是通过v,但是默认都通过version
REST_FRAMEWORK = {
"ALLOWED_VERSIONS":['V1','V2']
"VERSION_PARAM":"v"
} 9.所以以后加上版本控制只需要三步
9.1 在url路由中设置:url(r'^api/(?P<version>\w+)/', include('kka.urls')),
9.2 导入from rest_framework.versioning import URLPathVersioning,并在自己的类里面设置versioning_class = URLPathVersioning
9.3 在setting里面设置
REST_FRAMEWORK = {
"ALLOWED_VERSIONS":['V1','V2']
"VERSION_PARAM":"version"
} 全局使用版本控制
url中:
url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'),
url(r'^(?P<version>\w+)/users/$', users_list, name='users-list'), 在视图中使用:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.versioning import URLPathVersioning class OrderView(APIView): def get(self,request,*args,**kwargs):
print(request.version)
print(request.versioning_scheme)
return Response('...') def post(self,request,*args,**kwargs):
return Response('post')
setting设置:
REST_FRAMEWORK = {
"PAGE_SIZE":2,
"DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination",
"DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
"ALLOWED_VERSIONS":['v1','v2'],
'VERSION_PARAM':'version'
}

6.认证及其源码分析(面试的时候)

认证及其源码分析(面试的时候)
作用:判断用户是否登陆,根据等路状态来给用户指定访问的路径
其中drf提供了4种认证方式,最基础的时BaseAuthentication
简单用法:
1.路由分发
url(r'^api/(?P<version>\w+)/', include('kka.urls')),
2.路由匹配
urlpatterns = [
url(r'^order/$', views.Order.as_view()),
url(r'^user/$', views.User.as_view()),
url(r'^login/$', views.Login.as_view()),
]
3.视图函数
from . import models
import uuid
from rest_framework.authentication import BaseAuthentication
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get('token')
user_obj = models.UserInfo.objects.filter(token=token).first()
if user_obj:
return (user_obj,token)
#
return (None,None) class User(APIView):
authentication_classes = [MyAuthentication,]
def get(self,request,*args,**kwargs):
if request.user:
print(request.user)
print(request.auth)
# print(request.token)
return Response('user')
return Response('请登录~') class Login(APIView):
authentication_classes = [] # 这句话的意思是Login类不使用认证
def post(self,request,*args,**kwargs):
user_obj = models.UserInfo.objects.filter(**request.data).first()
if not user_obj:
return Response('登录失败')
random_string = str(uuid.uuid4()) # 生成随机字符串
user_obj.token = random_string
user_obj.save()
return Response(random_string)
源码分析
1.先走dispatch方法,并对请求(request)进行封装 request = self.initialize_request(request, *args, **kwargs)
2.在请求封装的时候执行了initialize_request里面封装了一个authenticators=self.get_authenticators(),
3.get_authenticators(),返回了了一个 return [auth() for auth in self.authentication_classes] #对象列表,是我们的认证类,进行实力化
4.authentication_classes可以在自己实例化侧程序中指定。 5.那么request.user和request.auth是如何封装的那??
5.1 在initialize_request封装请求的时候,返回的是return Request(xxx,xxx,xxx,)
5.2 在Request类里面可以看到user方法里面的self._authenticate(),调用Request类的自己的_authenticate
5.3 _authenticate里面循环的时for authenticator in self.authenticators:,其中 self.authenticators:是我们我们封装对象列表
5.4 其中 user_auth_tuple = authenticator.authenticate(self)返回的是一个元组, 其中authenticate执行的时我们类里面的authenticate方法
5.5 最后self.user, self.auth = user_auth_tuple,其中一个是用户名,一个是token,这是有返回值的情况下
其中:一种是正常的返回
一种是返回none,去进行下一个验证
一种是返回异常,就是认证失败 没有返回值的情况下
5.6 执行了self._not_authenticated()方法,其中self.user = api_settings.UNAUTHENTICATED_USER()
是配置文件里面的配置的匿名用户angmoseUser 6.可以将authentication_classes写在配置文件里面,这样就全部的视图函数都可以使用了,注意要等于一个列表
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLSAAES":["app的名字.文件名字.类名"]
}
7.什么时候会执行authentication这个认证的功能??(重点)
在调用request.user()的时候会执行这个功能 8.总结:
当用户发来请求时,找到认证的所有类并实例化成为对象列表,然后将对象列表封装到新的request对象中。
如果以后再视图中调用request.user,会在内部循环认证的对象列表,并执行每个对象的authenticate方法
该方法用于认证,他会返回两个值分别会赋值给request.user/request.auth 9.将登录函数让所有人都必须登录的话,只需要将authentication_classes=[],就设置好了 10.其实在认证组件里面,不管我们有没有主动调用requets.user,drf都会主动的帮助我们做认证
在dispatch里面的initial里面self.perform_authentication(request)已经执行了request.user,并将其赋值给self._user = request.user
当我们在想在我们程序里面调用的认证模块的时候,Request类的User方法会去验证当前是否存在self._user
如果存在说明,已经验证过了,就直接返回。如果不存在才会去验证
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user 所以没有看过源码的人,都会认为是在调用request.user的时候才会做认证,实际上是在版本初始化完成之后立即就会做认证。 就是将用户的信息复制到request.user里面,供我们以后使用

7.drf权限组件及源码分析

权限组件及其源码分析
就是将我们在认证的时候做的判断移到权限组件进行判断,而不是放在视图函数里面
视图函数专门写逻辑,而其他事情让其他组件去做,
注意:
在drf里面认证先执行,然后在执行权限 源码:
from rest_framework.permissions import BasePermission
from rest_framework import exceptions class Mypermission(BasePermission):
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
if request.user:
print(request.user) # 打印登录用户
print(request.auth) # 打印token
# print(request.token)
return True
raise exceptions.PermissionDenied({"code":"","messgae":"无权限~"}) def has_object_permission(self, request, view, obj):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True message = "无权限!" class User(APIView):
authentication_classes = [MyAuthentication,]
permission_classes = [Mypermission,]
def get(self,request,*args,**kwargs):
# if request.user:
# print(request.user) # 打印登录用户
# print(request.auth) # 打印token
# return Response('User')
# print(request.token)
return Response('User~') # settings配置
REST_FRAMEWORK = {
"PAGE_SIZE":2,
"DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination",
"DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
"ALLOWED_VERSIONS":['v1','v2'],
'VERSION_PARAM':'version',
"DEFAULT_AUTHENTICATION_CLASSES":["kka.auth.TokenAuthentication",]
}
全局使用:
在setting里面设置
如果有的页面不想使用,在视图里面设置permission_classes=[] 源码分析:
class APIView(View):
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES def dispatch(self, request, *args, **kwargs):
封装request对象
self.initial(request, *args, **kwargs)
通过反射执行视图中的方法 def initial(self, request, *args, **kwargs):
版本的处理
# 认证
self.perform_authentication(request) # 权限判断
self.check_permissions(request) # 访问频率的限制
self.check_throttles(request) def perform_authentication(self, request):
request.user def check_permissions(self, request):
# [对象,对象,]
for permission in self.get_permissions():
if not permission.has_permission(request, self):
self.permission_denied(request, message=getattr(permission, 'message', None))
def permission_denied(self, request, message=None):
if request.authenticators and not request.successful_authenticator:
raise exceptions.NotAuthenticated()
raise exceptions.PermissionDenied(detail=message) def get_permissions(self):
return [permission() for permission in self.permission_classes] class UserView(APIView):
permission_classes = [MyPermission, ] def get(self,request,*args,**kwargs):
return Response('user') 权限源码分析:
访问多条数据:has_permissions
在执行dispatch里面的inital的时候,会执行self.check_permissions(request),这就是在做权限的初始化
首先check_permissions调用了一个self.get_permissions(),会去我们自己的类里面去找,因为我们没有写所以
会去父类里面找,父类的get_permissions执行了一个self.permission_classes,也是先去我们写的类里面去找,
如果没有,就到配置文件里面去找DEFAULT_PERMISSION_CLASSES,如果还没有,就不使用这个功能
如果我们自己写了,就返回一个对象列表,和认证流程是差不多的。
在执行check_permissions时候,还会执行一个has_permission,判断是否有权限。
如果有权限,check_permissions里面的循环会继续向下走,如果没有权限,会执行permission_denied方法,并且
会在我们写的类里面去找message变量,返回报错信息,如果我们没有写message变量,就去执行父类的message 关于异常返回:
一般情况是都是源码帮助我们返回异常,并且不可定制,我们可以自己返回异常
from rest_framework import exceptions
raise exceptions.PermissionDenied({"code":"","error":"你没权限~"})
或者直接
return False 让源码去操作异常信息 其中二者区别是:
我们的permission_classes是一个权限列表,代表着好多权限,让依次验证的时候,如果产生错误,
源码都是返回的return F
alse,并不知道是那个权限类报错,如果自定义的raise的话,会比较明显的
知道是那个权限类报错了
获取单条数据:has_object_permission
其中has_object_permission,是在我们的类继承了RetrieveAPIView,才会被执行
在GenericAPIView里面有个get_object会去执行check_object_permissions里面的has_object_permission
所以has_object_permission判断的是访问单条数据的时候验证权限。
访问单条数据,并且通过has_object_permission方法,进行权限验证 总结:
不管什么请求都会进入到dispatch方法里面,并且都会走has_permission
只是如果单条数据数据的时候还会再走一次has_object_permissions再一次进行验证
实际上权限的验证就是执行以上两个方法,只有都通过了之后才会继续执行视图函数

pass

drf:restful概念,类继承关系,drf请求封装,drf请求流程,版本控制组件,认证组件(token),权限组件的更多相关文章

  1. Programming In Scala笔记-第十一章、Scala中的类继承关系

    本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...

  2. Unity类继承关系 图

    UnityEngine(命名空间) 其他命名空间 其他类 Object(类) 其他类(继承自Object) Component(类)(继承自Object) 其他类(继承自Component) Tran ...

  3. PythonI/O进阶学习笔记_4.自定义序列类(序列基类继承关系/可切片对象/推导式)

    前言: 本文代码基于python3 Content: 1.python中的序列类分类 2. python序列中abc基类继承关系 3. 由list的extend等方法来看序列类的一些特定方法 4. l ...

  4. Idea查看接口或类继承关系

    打开想要查看的接口或者类文件,使用快捷键CTRL+H调出Hierarchy窗口 比如,想要查看Exception的类继承关系,首先定位到这个文件,然后调出Hierarchy窗口. 该窗口上面的一排工具 ...

  5. C# Wpf Shape类继承关系

    Path派生于Shape namespace System.Windows.Shapes { public sealed class Path : Shape { // Path 派生于Shape } ...

  6. Restful 4 -- 认证组件、权限组件、频率组件、url注册器、响应器、分页器

    一.认证组件.权限组件.频率组件总结:  只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件 1.认证组件格式 写一个认 ...

  7. 【技术博客】Flutter—使用网络请求的页面搭建流程、State生命周期、一些组件的应用

    Flutter-使用网络请求的页面搭建流程.State生命周期.一些组件的应用 使用网络请求的页面搭建流程 ​ 在开发APP时,我们常常会遇到如下场景:进入一个页面后,要先进行网络调用,然后使用调用返 ...

  8. WebApi系列~基于单请求封装多请求的设计

    回到目录 怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能 ...

  9. webapi基于单请求封装多请求的设计【转】

    怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能包含多个子 ...

随机推荐

  1. java的spi(Service Provider Interface)机制及源码(java8)

    1.什么是java的spi spi 全称为 service provider interface 即 服务提供接口,用来作为服务的扩展发现.在运行时动态添加接口的实现,是对接口的实现类的创建管理. 2 ...

  2. 洛谷 P3368 【模板】树状数组 2(区间加,单点查询)

    题目链接 https://www.luogu.org/problemnew/show/P3368 树状数组 最基础的用法:https://www.cnblogs.com/yinyuqin/p/1096 ...

  3. 5、numpy——切片和索引

    1.一维数组 1.1 一维数组很简单,基本和列表一致.ndarray 数组可以基于 0 - n 的下标进行索引. 切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step ...

  4. 4、numpy——创建数组

    1.普通创建——np.array() 创建数组最简单的方法就是使用array函数.它接收一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组. import numpy as ...

  5. defer、panic和recover

    1. defer(1)defer用于将某个方法或语句推迟到当前函数返回的最后一刻执行,一般用于释放某些已分配的资源.函数返回的最后一刻指的是,return语句更新返回值变量之后,函数返回之前,所以de ...

  6. Python之反向迭代

    需求:得到反方向迭代一个序列解决:使用内置的 reversed() 函数 a = [1, 2, 3, 4] for x in reversed(a): print(x) # 4 3 2 1 反向迭代仅 ...

  7. navicat连接Oracle数据库提示错误 ORA-12514

    这个是服务名写错了,服务名的字段在Oracle安装路径里找 这个我的服务名,这好像是重装Oracle就会变我之前的事orcl,重装之后发现连接不上数据库了,就倔强着找到了它 备注:如果是连接远程Ora ...

  8. 关于手机端在同一个Grid中使用不同的布局展现即Layout的使用

    标题可能说的不是很清楚,我举个栗子好了,现在你正在写手机端的一个审批模块,这个模块要求能够展示所有待审批的信息 比如出差申请,请假申请,加班申请,以及报销申请 那么我的思路有两个 1:建立一个Tab页 ...

  9. C# 生成word文档(NPOI.XWPF)

    一.基础 1.创建Word using NPOI.XWPF.UserModel XWPFDocument doc = new XWPFDocument(); //创建新的word文档 XWPFPara ...

  10. Kvm --01 虚拟化基础概念

    目录 1. 虚拟化基础概念 01. 什么是虚拟化? 02. 为什么要用虚拟化? 03. 虚拟化在企业中的应用场景? 04. 虚拟化软件介绍 05. Kvm介绍 2. 安装部署Kvm 3. Kvm虚拟机 ...