🍡 Django - Views
Views
Updated at 2018-04-04 02: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.htmltemplate and provides model of typemodelwith primary key ofpkin the url.generic.ListView: expects<app name>/<model name>_list.htmltemplate and providescontext_object_namequeryset provided byget_queryset()method orquerysetattribute.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'