Django 소스 읽기 노트(기본 보기)
View
, ContextMixin
, TemplateResponseMixin
, TemplateView
, RedirectView
View class View(object):
"""
1 http_method_names
2 , , 。
"""
# " "
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
def __init__(self, **kwargs):
"""
,kwargs
"""
# , ,
for key, value in six.iteritems(kwargs):
setattr(self, key, value)
@classonlymethod #
def as_view(cls, **initkwargs):
"""
(view)
:1 http_method_names
2 self , , :query_set
eg: View.as_view(query_set=User.object.all())
URLconf User
"""
for key in initkwargs: #
if key in cls.http_method_names:
# http http_method_names
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
# Response/Request
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key))
def view(request, *args, **kwargs):
""" """
self = cls(**initkwargs) # initkwargs as_view()
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get # get
self.request = request # WSGI
self.args = args # URL
self.kwargs = kwargs # URL
return self.dispatch(request, *args, **kwargs) # dispatch
# view_class view_initkwargs
view.view_class = cls
view.view_initkwargs = initkwargs #
# take name and docstring from class
update_wrapper(view, cls, updated=())
# and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
#
if request.method.lower() in self.http_method_names: # WSGIRequest 。
# get/post... http_method_names ( )。( View http_method_names )
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
# `Method Not Allowed...`
handler = self.http_method_not_allowed
#
return handler(request, *args, **kwargs)
def http_method_not_allowed(self, request, *args, **kwargs):
#
logger.warning(
'Method Not Allowed (%s): %s', request.method, request.path,
extra={'status_code': 405, 'request': request}
)
return http.HttpResponseNotAllowed(self._allowed_methods())
def options(self, request, *args, **kwargs):
"""
options(request,* args,** kwargs)
OPTIONS HTTP 。 , Allow HTTP 。
Handles responding to requests for the OPTIONS HTTP verb.
"""
response = http.HttpResponse()
response['Allow'] = ', '.join(self._allowed_methods())
response['Content-Length'] = '0'
return response
def _allowed_methods(self):
# View http_method_names ,
# hasattr 。 。
#
return [m.upper() for m in self.http_method_names if hasattr(self, m)]
ContextMixin
class ContextMixin(object):
"""
, , ,
, 。
"""
def get_context_data(self, **kwargs):
# view View 。
if 'view' not in kwargs:
kwargs['view'] = self
return kwargs
# demo
def get_context_data(**kwargs)
context = super().get_context_data(**kwargs)
context.update({"name": "monkey",
"gender": "male"})
return context
TemplateResponseMixin
class TemplateResponseMixin(object):
"""
, , 。
django
"""
template_name = None # HTML None django.core.exceptions.ImproperlyConfigured 。 1.18
template_engine = None # , settings
# Django jinja2
# 1 'django.template.backends.django.DjangoTemplates'
# 2 'django.template.backends.jinja2.Jinja2'
response_class = TemplateResponse # TemplateResponse
# render_to_response , , respone_class
content_type = None # MIME。content_type response_class。 None- Django 'text/html'
def render_to_response(self, context, **response_kwargs):
"""
HTML response_kwargs 。 ( ) HttpRespone 。
。
: context
context context
get_context_data() , , 。
"""
response_kwargs.setdefault('content_type', self.content_type)
return self.response_class(
request=self.request,
template=self.get_template_names(),
context=context,
using=self.template_engine,
**response_kwargs
)
def get_template_names(self):
"""
, 。
render_to_response response_class ,
render_to_response , 。
"""
if self.template_name is None: # ~
raise ImproperlyConfigured(
"TemplateResponseMixin requires either a definition of "
"'template_name' or an implementation of 'get_template_names()'")
else:
return [self.template_name] #
TemplateView
#
# View , get URLconf
# TemplateResponseMixin template_name
#
class TemplateView(TemplateResponseMixin, ContextMixin, View):
"""
, get 。
"""
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
RedirectView
# View get , get <:>
class RedirectView(View):
"""
, GET get
"""
permanent = False # 。 HTTP 。 True, 301。 False, 302。 permanent False。
url = None # URL
pattern_name = None # url
query_string = False # URL URL True
def get_redirect_url(self, *args, **kwargs):
"""
URL ( query_string URL )
"""
if self.url: # url
url = self.url % kwargs
elif self.pattern_name: # URL
try:
url = reverse(self.pattern_name, args=args, kwargs=kwargs)
except NoReverseMatch:
return None
else:
return None # url pattern_name None
args = self.request.META.get('QUERY_STRING', '') # get 'QUERY_STRING' , ''
if args and self.query_string: # query_string url
url = "%s?%s" % (url, args)
return url
def get(self, request, *args, **kwargs):
# get url get_redirect_url
url = self.get_redirect_url(*args, **kwargs)
if url: # URL
if self.permanent: # True 301 False 302
return http.HttpResponsePermanentRedirect(url) #
else:
return http.HttpResponseRedirect(url) # < status_code = 302 >
else: # URL !410
logger.warning(
'Gone: %s', request.path,
extra={'status_code': 410, 'request': request}
)
return http.HttpResponseGone() # 410
# get
def head(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def options(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.