It will be a learning memo article for beginners. Note how as_view () used in Django's generic views works. If you can understand this, I think you can understand and implement View, which is the basis of general-purpose views.
Described when using a generic view when writing a route to the urls.py file in Django. The following is a usage example.
urls.py
from django.urls import path
from . import views
app_name = 'recipe'
urlpatterns = [
path('', views.[name of the class].as_view(), name='index'),
]
views.py
from django.views.generic import TemplateView
class RecipeListView(TemplateView):
"""
Template view class
"""
template_name = '[Application name]/index.html'
With this implementation, the contents of index.html will be displayed on the page accessed by the root path.
In the above implementation, "TemplateView" is inherited to implement a general-purpose view, but "TemplateView" inherits "View". Below is the source of "View". (Excerpt only from the explanation)
django/django/views/generic/base.py
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(
'The method name %s is not accepted as a keyword argument '
'to %s().' % (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)
self.setup(request, *args, **kwargs)
if not hasattr(self, 'request'):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
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)
:
:
as_view () returns the dippatch method as a return value. The dippatch method is implemented to call the methods (get and post) defined in http_method_names. Therefore, as_view () calls get () and post () of the general view in response to the request fired from the client.
By the way, get () of "TemplateView" has the following contents, and render_to_response is returned as a return value.
django/django/views/generic/base.py
class TemplateView(TemplateResponseMixin, ContextMixin, View):
"""Render a template."""
def get(self, request, *args, **kwargs):
# RemovedInDjango40Warning: when the deprecation ends, replace with:
# context = self.get_context_data()
context_kwargs = _wrap_url_kwargs_with_deprecation_warning(kwargs)
context = self.get_context_data(**context_kwargs)
return self.render_to_response(context)
that's all.
Understand the Django generic class view implementation (https://qiita.com/shinno21/items/831811c5b6fae31f7c99) Django base.py
Recommended Posts