[PYTHON] [Django] as_view () notes

[Django] as_view () notes

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.

Example of using as_view ()

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.

What is as_view ()?

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.

reference

Understand the Django generic class view implementation (https://qiita.com/shinno21/items/831811c5b6fae31f7c99) Django base.py

Recommended Posts

[Django] as_view () notes
django notes
Django notes
Django Template notes
[Django] JWT notes
Celery notes on Django
[Personal notes] Python, Django
[Django] Notes on using django-debug-toolbar
Django
[Django] Directory structure practices + notes
Launch notes for existing Django applications
django update
Django note 4
Step notes to get started with django
JetBrains_Learning Notes_003
Django memorandum
django search
Django installation
Django Summary
pyenv notes
Django test
Miscellaneous notes about the Django REST framework
Notes on creating static files in Django
Django # 2 (template)
SQL notes
Pandas notes
Django Note 5
Sphinx notes
Django hands-on
Touch django
Django Summary
Django basics
Django Shoho
Django defaults
Jupyter_Learning Notes_000
Django + Docker
Django Glossary
Django search
Install Django
Django: References
Django Note 1
Django note 3
Django note 2
Django novice addicted error and solution notes
Django startup
Django NullCharField