1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
|
==========
Base views
==========
The following three classes provide much of the functionality needed to create
Django views. You may think of them as *parent* views, which can be used by
themselves or inherited from. They may not provide all the capabilities
required for projects, in which case there are Mixins and Generic class-based
views.
Many of Django's built-in class-based views inherit from other class-based
views or various mixins. Because this inheritance chain is very important, the
ancestor classes are documented under the section title of **Ancestors (MRO)**.
MRO is an acronym for Method Resolution Order.
``View``
========
.. class:: django.views.generic.base.View
The base view class. All other class-based views inherit from this base
class. It isn't strictly a generic view and thus can also be imported from
``django.views``.
**Method Flowchart**
#. :meth:`setup()`
#. :meth:`dispatch()`
#. :meth:`http_method_not_allowed()`
#. :meth:`options()`
**Example views.py**::
from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request, *args, **kwargs):
return HttpResponse("Hello, World!")
**Example urls.py**::
from django.urls import path
from myapp.views import MyView
urlpatterns = [
path("mine/", MyView.as_view(), name="my-view"),
]
**Attributes**
.. attribute:: http_method_names
The list of HTTP method names that this view will accept.
Default::
["get", "post", "put", "patch", "delete", "head", "options", "trace"]
**Methods**
.. classmethod:: as_view(**initkwargs)
Returns a callable view that takes a request and returns a response::
response = MyView.as_view()(request)
The returned view has ``view_class`` and ``view_initkwargs``
attributes.
When the view is called during the request/response cycle, the
:meth:`setup` method assigns the :class:`~django.http.HttpRequest` to
the view's ``request`` attribute, and any positional and/or keyword
arguments :ref:`captured from the URL pattern
<how-django-processes-a-request>` to the ``args`` and ``kwargs``
attributes, respectively. Then :meth:`dispatch` is called.
If a ``View`` subclass defines asynchronous (``async def``) method
handlers, ``as_view()`` will mark the returned callable as a coroutine
function. An ``ImproperlyConfigured`` exception will be raised if both
asynchronous (``async def``) and synchronous (``def``) handlers are
defined on a single view-class.
.. versionchanged:: 4.1
Compatibility with asynchronous (``async def``) method handlers was
added.
.. method:: setup(request, *args, **kwargs)
Performs key view initialization prior to :meth:`dispatch`.
If overriding this method, you must call ``super()``.
.. method:: dispatch(request, *args, **kwargs)
The ``view`` part of the view -- the method that accepts a ``request``
argument plus arguments, and returns an HTTP response.
The default implementation will inspect the HTTP method and attempt to
delegate to a method that matches the HTTP method; a ``GET`` will be
delegated to ``get()``, a ``POST`` to ``post()``, and so on.
By default, a ``HEAD`` request will be delegated to ``get()``.
If you need to handle ``HEAD`` requests in a different way than ``GET``,
you can override the ``head()`` method. See
:ref:`supporting-other-http-methods` for an example.
.. method:: http_method_not_allowed(request, *args, **kwargs)
If the view was called with an HTTP method it doesn't support, this
method is called instead.
The default implementation returns ``HttpResponseNotAllowed`` with a
list of allowed methods in plain text.
.. method:: options(request, *args, **kwargs)
Handles responding to requests for the OPTIONS HTTP verb. Returns a
response with the ``Allow`` header containing a list of the view's
allowed HTTP method names.
If the other HTTP methods handlers on the class are asynchronous
(``async def``) then the response will be wrapped in a coroutine
function for use with ``await``.
.. versionchanged:: 4.1
Compatibility with classes defining asynchronous (``async def``)
method handlers was added.
``TemplateView``
================
.. class:: django.views.generic.base.TemplateView
Renders a given template, with the context containing parameters captured
in the URL.
**Ancestors (MRO)**
This view inherits methods and attributes from the following views:
* :class:`django.views.generic.base.TemplateResponseMixin`
* :class:`django.views.generic.base.ContextMixin`
* :class:`django.views.generic.base.View`
**Method Flowchart**
#. :meth:`~django.views.generic.base.View.setup()`
#. :meth:`~django.views.generic.base.View.dispatch()`
#. :meth:`~django.views.generic.base.View.http_method_not_allowed()`
#. :meth:`~django.views.generic.base.ContextMixin.get_context_data()`
**Example views.py**::
from django.views.generic.base import TemplateView
from articles.models import Article
class HomePageView(TemplateView):
template_name = "home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["latest_articles"] = Article.objects.all()[:5]
return context
**Example urls.py**::
from django.urls import path
from myapp.views import HomePageView
urlpatterns = [
path("", HomePageView.as_view(), name="home"),
]
**Context**
* Populated (through :class:`~django.views.generic.base.ContextMixin`) with
the keyword arguments captured from the URL pattern that served the view.
* You can also add context using the
:attr:`~django.views.generic.base.ContextMixin.extra_context` keyword
argument for :meth:`~django.views.generic.base.View.as_view`.
``RedirectView``
================
.. class:: django.views.generic.base.RedirectView
Redirects to a given URL.
The given URL may contain dictionary-style string formatting, which will be
interpolated against the parameters captured in the URL. Because keyword
interpolation is *always* done (even if no arguments are passed in), any
``"%"`` characters in the URL must be written as ``"%%"`` so that Python
will convert them to a single percent sign on output.
If the given URL is ``None``, Django will return an ``HttpResponseGone``
(410).
**Ancestors (MRO)**
This view inherits methods and attributes from the following view:
* :class:`django.views.generic.base.View`
**Method Flowchart**
#. :meth:`~django.views.generic.base.View.setup()`
#. :meth:`~django.views.generic.base.View.dispatch()`
#. :meth:`~django.views.generic.base.View.http_method_not_allowed()`
#. :meth:`get_redirect_url()`
**Example views.py**::
from django.shortcuts import get_object_or_404
from django.views.generic.base import RedirectView
from articles.models import Article
class ArticleCounterRedirectView(RedirectView):
permanent = False
query_string = True
pattern_name = "article-detail"
def get_redirect_url(self, *args, **kwargs):
article = get_object_or_404(Article, pk=kwargs["pk"])
article.update_counter()
return super().get_redirect_url(*args, **kwargs)
**Example urls.py**::
from django.urls import path
from django.views.generic.base import RedirectView
from article.views import ArticleCounterRedirectView, ArticleDetailView
urlpatterns = [
path(
"counter/<int:pk>/",
ArticleCounterRedirectView.as_view(),
name="article-counter",
),
path("details/<int:pk>/", ArticleDetailView.as_view(), name="article-detail"),
path(
"go-to-django/",
RedirectView.as_view(url="https://www.djangoproject.com/"),
name="go-to-django",
),
]
**Attributes**
.. attribute:: url
The URL to redirect to, as a string. Or ``None`` to raise a 410 (Gone)
HTTP error.
.. attribute:: pattern_name
The name of the URL pattern to redirect to. Reversing will be done
using the same args and kwargs as are passed in for this view.
.. attribute:: permanent
Whether the redirect should be permanent. The only difference here is
the HTTP status code returned. If ``True``, then the redirect will use
status code 301. If ``False``, then the redirect will use status code
302. By default, ``permanent`` is ``False``.
.. attribute:: query_string
Whether to pass along the GET query string to the new location. If
``True``, then the query string is appended to the URL. If ``False``,
then the query string is discarded. By default, ``query_string`` is
``False``.
**Methods**
.. method:: get_redirect_url(*args, **kwargs)
Constructs the target URL for redirection.
The ``args`` and ``kwargs`` arguments are positional and/or keyword
arguments :ref:`captured from the URL pattern
<how-django-processes-a-request>`, respectively.
The default implementation uses :attr:`url` as a starting
string and performs expansion of ``%`` named parameters in that string
using the named groups captured in the URL.
If :attr:`url` is not set, ``get_redirect_url()`` tries to reverse the
:attr:`pattern_name` using what was captured in the URL (both named and
unnamed groups are used).
If requested by :attr:`query_string`, it will also append the query
string to the generated URL.
Subclasses may implement any behavior they wish, as long as the method
returns a redirect-ready URL string.
|