Django - Views
Updated at 2018-04-03 23:49
Django view is a callable that takes a request and returns a response.
from django.http import HttpResponse
def my_view(request):
return HttpResponse('result')
Views frequently render a template.
from django.shortcuts import render
def about_view(request):
return render(request, 'about.html')
Django views can be class-based. Then the class ancestry must contain View
base class.
from django.views.generic import TemplateView
TemplateView.as_view(template_name='about.html')
# or the same but as a fully defined class...
class AboutView(TemplateView):
template_name = 'about.html'
AboutView.as_view()
View class lifecycle starts with dispatch and ends in HTTP response.
COMMON LIFECYCLE OVERVIEW:
> Django calls dispatch on the view class
> dispatch with optional HTTP method selection
> HTTP method function (get, post, etc.) on the view class
> returns HttpResponse
> Django uses the HttpResponse as the base for the response
class View(object):
# ...
def dispatch(self, request, *args, **kwargs):
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)
# ...
# where the dispatch routes it back up to less abstract class that
# defines different HTTP method responses, e.g.
class TemplateView(TemplateResponseMixin, ContextMixin, View):
# ...
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
# ...
# these HTTP method functions return an instance of HttpResponse
return HttpResponse(status=405, content='POST only')
# HttpResponse defines content, content type, status, headers, cookies etc.
# all that is required for serialization and sending the response
class HttpResponse(HttpResponseBase):
# ...
def __init__(self, content=b'', *args, **kwargs):
super(HttpResponse, self).__init__(*args, **kwargs)
self.content = content
# ...
Here are some commonly extended views:
django.views.View
: url.py linking and basic http method handling.generic.TemplateView
: renders template namedtemplate_name
.generic.DetailView
: expects<app name>/<model name>_detail.html
template and provides model of typemodel
with primary key ofpk
in the url.generic.ListView
: expects<app name>/<model name>_list.html
template and providescontext_object_name
queryset provided byget_queryset()
method orqueryset
attribute.generic.RedirectView
: TODOgeneric.FormView
: TODOgeneric.CreateView
: TODOgeneric.UpdateView
: TODOgeneric.DeleteView
: TODOgeneric.ArchiveIndexView
: TODOgeneric.YearArchiveView
: TODOgeneric.MonthArchiveView
: TODOgeneric.WeekArchiveView
: TODOgeneric.DayArchiveView
: TODOgeneric.TodayArchiveView
: TODOgeneric.DateDetailView
: TODO
Some generic views can also be used as functions:
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^about/$', TemplateView.as_view(template_name="about.html")),
]
# compared to normal usage:
from django.conf.urls import url
from someapp.views import AboutView
urlpatterns = [
url(r'^about/$', AboutView.as_view()),
]
Interesting attributes and methods that can be overwitten:
template_name
: which template to render.get_context_data()
: the context when rendering the template.render_to_response()
: how template rendering happens, usually not customized.get()
: what GET request returns, usually HttpResponse.post()
: what POST request returns, usually HttpResponseRedirect or HttpResponse.head()
: what HEAD request returns, usually empty HttpResponse with headers.
TODO: https://docs.djangoproject.com/en/1.10/topics/class-based-views/
Mixins
If you would like to inherit from multiple generic views; inherit from View
and add other views as mixins.
For example, here is how TemplateView
is defined:
class TemplateView(TemplateResponseMixin, ContextMixin, View):
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
Mixin list:
TemplateResponseMixin
: A mixin that can be used to render a template.ContextMixin
: Provides method for template context definition.SingleObjectMixin
: Provides a mechanism for looking up an object associated with the current HTTP request.SingleObjectTemplateResponseMixin
: A mixin class that performs template-based response rendering for views that operate upon a single object instance.MultipleObjectMixin
: A mixin that can be used to lookup a list of objects associated with the current HTTP request.MultipleObjectTemplateResponseMixin
: A mixin class that performs template-based response rendering for views that operate upon a list of object instances.FormMixin
: A mixin class that provides facilities for creating and displaying forms.ModelFormMixin
: A form mixin that works on ModelForms, rather than a standalone form.ProcessFormView
: A mixin that provides basic HTTP GET and POST workflow.DeletionMixin
: Enables handling of the DELETE http action.YearMixin
: A mixin that can be used to retrieve and provide parsing information for a year component of a date.MonthMixin
: The same as previous but month.DayMixin
: The same as previous but day.WeekMixin
: The same as previous but week.DateMixin
: A mixin class providing common behavior for all date-based views.BaseDateListView
: A base class that provides common behavior for all date-based views.
View Decorators
Common or frequently changing functionality between views can be added to decorators.
decorators = [never_cache, login_required]
@method_decorator(decorators, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
@method_decorator(never_cache, name='dispatch')
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'