@classonlymethoddefas_view(cls,**initkwargs):"""Main entry point for a request-response process."""forkeyininitkwargs:ifkeyincls.http_method_names:raiseTypeError('The method name %s is not accepted as a keyword argument ''to %s().'%(key,cls.__name__))ifnothasattr(cls,key):raiseTypeError("%s() received an invalid keyword %r. as_view ""only accepts arguments that are already ""attributes of the class."%(cls.__name__,key))defview(request,*args,**kwargs):self=cls(**initkwargs)self.setup(request,*args,**kwargs)ifnothasattr(self,'request'):raiseAttributeError("%s instance has no 'request' attribute. Did you override ""setup() and forget to call super()?"%cls.__name__)returnself.dispatch(request,*args,**kwargs)view.view_class=clsview.view_initkwargs=initkwargs# take name and docstring from classupdate_wrapper(view,cls,updated=())# and possible attributes set by decorators# like csrf_exempt from dispatchupdate_wrapper(view,cls.dispatch,assigned=())returnview
90
91
92
93
94
95
96
97
98
defdispatch(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.ifrequest.method.lower()inself.http_method_names:handler=getattr(self,request.method.lower(),self.http_method_not_allowed)else:handler=self.http_method_not_allowedreturnhandler(request,*args,**kwargs)
defget(self,request,*args,**kwargs):self.object_list=self.get_queryset()allow_empty=self.get_allow_empty()ifnotallow_empty:# When pagination is enabled and object_list is a queryset,# it's better to do a cheap query than to load the unpaginated# queryset in memory.ifself.get_paginate_by(self.object_list)isnotNoneandhasattr(self.object_list,'exists'):is_empty=notself.object_list.exists()else:is_empty=notself.object_listifis_empty:raiseHttp404(_('Empty list and “%(class_name)s.allow_empty” is False.')%{'class_name':self.__class__.__name__,})context=self.get_context_data()returnself.render_to_response(context)
Return ``True`` if the view should display empty lists and ``False``
if a 404 should be raised instead.
97
98
99
100
101
102
defget_allow_empty(self):""" Return ``True`` if the view should display empty lists and ``False`` if a 404 should be raised instead. """returnself.allow_empty
defget_context_data(self,*,object_list=None,**kwargs):"""Get the context for this view."""queryset=object_listifobject_listisnotNoneelseself.object_listpage_size=self.get_paginate_by(queryset)context_object_name=self.get_context_object_name(queryset)ifpage_size:paginator,page,queryset,is_paginated=self.paginate_queryset(queryset,page_size)context={'paginator':paginator,'page_obj':page,'is_paginated':is_paginated,'object_list':queryset}else:context={'paginator':None,'page_obj':None,'is_paginated':False,'object_list':queryset}ifcontext_object_nameisnotNone:context[context_object_name]=querysetcontext.update(kwargs)returnsuper().get_context_data(**context)
Get the name of the item to be used in the context.
104
105
106
107
108
109
110
111
defget_context_object_name(self,object_list):"""Get the name of the item to be used in the context."""ifself.context_object_name:returnself.context_object_nameelifhasattr(object_list,'model'):return'%s_list'%object_list.model._meta.model_nameelse:returnNone
Return the field or fields to use for ordering the queryset.
50
51
52
defget_ordering(self):"""Return the field or fields to use for ordering the queryset."""returnself.ordering
Get the number of items to paginate by, or ``None`` for no pagination.
77
78
79
80
81
defget_paginate_by(self,queryset):""" Get the number of items to paginate by, or ``None`` for no pagination. """returnself.paginate_by
Return the maximum number of orphans extend the last page by when
paginating.
90
91
92
93
94
95
defget_paginate_orphans(self):""" Return the maximum number of orphans extend the last page by when paginating. """returnself.paginate_orphans
Return an instance of the paginator for this view.
83
84
85
86
87
88
defget_paginator(self,queryset,per_page,orphans=0,allow_empty_first_page=True,**kwargs):"""Return an instance of the paginator for this view."""returnself.paginator_class(queryset,per_page,orphans=orphans,allow_empty_first_page=allow_empty_first_page,**kwargs)
Return the list of items for this view.
The return value must be an iterable and may be an instance of
`QuerySet` in which case `QuerySet` specific behavior will be enabled.
defget_queryset(self):""" Return the list of items for this view. The return value must be an iterable and may be an instance of `QuerySet` in which case `QuerySet` specific behavior will be enabled. """ifself.querysetisnotNone:queryset=self.querysetifisinstance(queryset,QuerySet):queryset=queryset.all()elifself.modelisnotNone:queryset=self.model._default_manager.all()else:raiseImproperlyConfigured("%(cls)s is missing a QuerySet. Define ""%(cls)s.model, %(cls)s.queryset, or override ""%(cls)s.get_queryset()."%{'cls':self.__class__.__name__})ordering=self.get_ordering()ifordering:ifisinstance(ordering,str):ordering=(ordering,)queryset=queryset.order_by(*ordering)returnqueryset
MultipleObjectTemplateResponseMixin
Return a list of template names to be used for the request. Must return
a list. May not be called if render_to_response is overridden.
defget_template_names(self):""" Return a list of template names to be used for the request. Must return a list. May not be called if render_to_response is overridden. """try:names=super().get_template_names()exceptImproperlyConfigured:# If template_name isn't specified, it's not a problem --# we just start with an empty list.names=[]# If the list is a queryset, we'll invent a template name based on the# app and model name. This name gets put at the end of the template# name list so that user-supplied names override the automatically-# generated ones.ifhasattr(self.object_list,'model'):opts=self.object_list.model._metanames.append("%s/%s%s.html"%(opts.app_label,opts.model_name,self.template_name_suffix))elifnotnames:raiseImproperlyConfigured("%(cls)s requires either a 'template_name' attribute ""or a get_queryset() method that returns a QuerySet."%{'cls':self.__class__.__name__,})returnnames
TemplateResponseMixin
Return a list of template names to be used for the request. Must return
a list. May not be called if render_to_response() is overridden.
141
142
143
144
145
146
147
148
149
150
151
defget_template_names(self):""" Return a list of template names to be used for the request. Must return a list. May not be called if render_to_response() is overridden. """ifself.template_nameisNone:raiseImproperlyConfigured("TemplateResponseMixin requires either a definition of ""'template_name' or an implementation of 'get_template_names()'")else:return[self.template_name]
100
101
102
103
104
105
defhttp_method_not_allowed(self,request,*args,**kwargs):logger.warning('Method Not Allowed (%s): %s',request.method,request.path,extra={'status_code':405,'request':request})returnHttpResponseNotAllowed(self._allowed_methods())
Handle responding to requests for the OPTIONS HTTP verb.
107
108
109
110
111
112
defoptions(self,request,*args,**kwargs):"""Handle responding to requests for the OPTIONS HTTP verb."""response=HttpResponse()response.headers['Allow']=', '.join(self._allowed_methods())response.headers['Content-Length']='0'returnresponse
defpaginate_queryset(self,queryset,page_size):"""Paginate the queryset, if needed."""paginator=self.get_paginator(queryset,page_size,orphans=self.get_paginate_orphans(),allow_empty_first_page=self.get_allow_empty())page_kwarg=self.page_kwargpage=self.kwargs.get(page_kwarg)orself.request.GET.get(page_kwarg)or1try:page_number=int(page)exceptValueError:ifpage=='last':page_number=paginator.num_pageselse:raiseHttp404(_('Page is not “last”, nor can it be converted to an int.'))try:page=paginator.page(page_number)return(paginator,page,page.object_list,page.has_other_pages())exceptInvalidPagease:raiseHttp404(_('Invalid page (%(page_number)s): %(message)s')%{'page_number':page_number,'message':str(e)})
Return a response, using the `response_class` for this view, with a
template rendered with the given context.
Pass response_kwargs to the constructor of the response class.
defrender_to_response(self,context,**response_kwargs):""" Return a response, using the `response_class` for this view, with a template rendered with the given context. Pass response_kwargs to the constructor of the response class. """response_kwargs.setdefault('content_type',self.content_type)returnself.response_class(request=self.request,template=self.get_template_names(),context=context,using=self.template_engine,**response_kwargs)
Initialize attributes shared by all view methods.
82
83
84
85
86
87
88
defsetup(self,request,*args,**kwargs):"""Initialize attributes shared by all view methods."""ifhasattr(self,'get')andnothasattr(self,'head'):self.head=self.getself.request=requestself.args=argsself.kwargs=kwargs
Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.
38
39
40
41
42
43
44
45
46
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.forkey,valueinkwargs.items():setattr(self,key,value)