Created
January 9, 2018 03:12
-
-
Save vimiix/cfca1fa75c8c1e500ddfab0bb2901f4f to your computer and use it in GitHub Desktop.
view class in Django.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class View: | |
""" | |
Intentionally simple parent class for all views. Only implements | |
dispatch-by-method and simple sanity checking. | |
""" | |
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] | |
def __init__(self, **kwargs): | |
""" | |
Constructor. Called in the URLconf; can contain helpful extra | |
keyword arguments, and other things. | |
""" | |
# Go through keyword arguments, and either save their values to our | |
# instance, or raise an error. | |
for key, value in kwargs.items(): | |
setattr(self, key, value) | |
@classonlymethod | |
def as_view(cls, **initkwargs): | |
"""Main entry point for a request-response process.""" | |
for key in initkwargs: | |
if key in cls.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): | |
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) | |
if hasattr(self, 'get') and not hasattr(self, 'head'): | |
self.head = self.get | |
self.request = request | |
self.args = args | |
self.kwargs = kwargs | |
return self.dispatch(request, *args, **kwargs) | |
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: | |
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) | |
else: | |
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 HttpResponseNotAllowed(self._allowed_methods()) | |
def options(self, request, *args, **kwargs): | |
"""Handle responding to requests for the OPTIONS HTTP verb.""" | |
response = HttpResponse() | |
response['Allow'] = ', '.join(self._allowed_methods()) | |
response['Content-Length'] = '0' | |
return response | |
def _allowed_methods(self): | |
return [m.upper() for m in self.http_method_names if hasattr(self, m)] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment