创建drf流程
配置文件
- pip install django==3.2
- django-admin startproject obj . 创建项目 加点会加到根目录
- python manege.py startapp app01
- pip install djangorestframework 按照drf组件
纯净版本django 设置
settings drf配置
REST_FRAMEWORK={}
查找这个REST_FRAMEWORK的方法流程
- from rest_framework.decorators import APIView
- APIView - api_settings - reload_api_settings 的方法
UNAUTHENTICATED:None
查找这个UNAUTHENTICATED的方法流程
- APIView - dispach - initialize_request - Request - def user - self._authenticate() - self._not_authenticated()
版本
视图的使用
settings的设置
怎么去找到VERSION_PARAM
- from rest_framework.versioning import QueryParameterVersioning
- QueryParameterVersioning - BaseVersioning -VERSION_PARAM
基于GET参数-反向生成URL
执行流程
class BaseVersioning:
default_version = api_settings.DEFAULT_VERSION
allowed_versions = api_settings.ALLOWED_VERSIONS
version_param = api_settings.VERSION_PARAM
def determine_version(self, request, *args, **kwargs):
msg = '{cls}.determine_version() must be implemented.'
raise NotImplementedError(msg.format(
cls=self.__class__.__name__
))
def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
return _reverse(viewname, args, kwargs, request, format, **extra)
def is_allowed_version(self, version):
if not self.allowed_versions:
return True
return ((version is not None and version == self.default_version) or
(version in self.allowed_versions))
class QueryParameterVersioning(BaseVersioning):
"""
GET /something/?version=0.1 HTTP/1.1
Host: example.com
Accept: application/json
"""
invalid_version_message = _('Invalid version in query parameter.')
#用来提取版本
def determine_version(self, request, *args, **kwargs):
version = request.query_params.get(self.version_param, self.default_version)
if not self.is_allowed_version(version):
raise exceptions.NotFound(self.invalid_version_message)
return version
#用来反向生成url
def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
#本质上是调用django上的reverse
url = super().reverse(
viewname, args, kwargs, request, format, **extra
)
if request.version is not None:
return replace_query_param(url, self.version_param, request.version)
return url
class APIView(View):
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS #如果没有配置version versioning_class 走这里
def determine_version(self, request, *args, **kwargs):
"""
If versioning is being used, then determine any API version for the
incoming request. Returns a two-tuple of (version, versioning_scheme)
"""
if self.versioning_class is None:
return (None, None)
scheme = self.versioning_class()#这里指的是我views定义的那个类,类后面加()进行实例化。
return (scheme.determine_version(request, *args, **kwargs), scheme)
def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs)
# Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
# Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs) # 1主要是先走这里
request.version, request.versioning_scheme = version, scheme
# Ensure that the incoming request is permitted
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
class LoginView(APIView):
versioning_class = QueryParameterVersioning
def get(self, request):
print(request.version)
print(request.versioning_scheme)
url = request.versioning_scheme.reverse("hh",request=request)
print("反向生成url:", url)
return Response("......")
单独对reverses分析
def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
#本质上是调用django上的reverse
url = super().reverse(
viewname, args, kwargs, request, format, **extra
)
if request.version is not None:
return replace_query_param(url, self.version_param, request.version)
return url
def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
return _reverse(viewname, args, kwargs, request, format, **extra)
def _reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra):
"""
Same as `django.urls.reverse`, but optionally takes a request
and returns a fully qualified URL, using the request to get the base URL.
"""
if format is not None:
kwargs = kwargs or {}
kwargs['format'] = format
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
if urlconf is None:
urlconf = get_urlconf()
resolver = get_resolver(urlconf)
args = args or []
kwargs = kwargs or {}
prefix = get_script_prefix()
if not isinstance(viewname, str):
view = viewname
else:
*path, view = viewname.split(':')
if current_app:
current_path = current_app.split(':')
current_path.reverse()
else:
current_path = None
resolved_path = []
ns_pattern = ''
ns_converters = {}
for ns in path:
current_ns = current_path.pop() if current_path else None
# Lookup the name to see if it could be an app identifier.
try:
app_list = resolver.app_dict[ns]
# Yes! Path part matches an app in the current Resolver.
if current_ns and current_ns in app_list:
# If we are reversing for a particular app, use that
# namespace.
ns = current_ns
elif ns not in app_list:
# The name isn't shared by one of the instances (i.e.,
# the default) so pick the first instance as the default.
ns = app_list[0]
except KeyError:
pass
if ns != current_ns:
current_path = None
try:
extra, resolver = resolver.namespace_dict[ns]
resolved_path.append(ns)
ns_pattern = ns_pattern + extra
ns_converters.update(resolver.pattern.converters)
except KeyError as key:
if resolved_path:
raise NoReverseMatch(
"%s is not a registered namespace inside '%s'" %
(key, ':'.join(resolved_path))
)
else:
raise NoReverseMatch("%s is not a registered namespace" % key)
if ns_pattern:
resolver = get_ns_resolver(ns_pattern, resolver, tuple(ns_converters.items()))
return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
reverse_lazy = lazy(reverse, str)
url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
if request:
return request.build_absolute_uri(url)
return url
标签:None,self,request,version,版本,kwargs,组件,ns,drf
From: https://www.cnblogs.com/bxj123/p/17774804.html