@classonlymethoddefas_view(cls,**initkwargs):""" Main entry point for a request-response process. """# sanitize keyword argumentsforkeyininitkwargs:ifkeyincls.http_method_names:raiseTypeError("You tried to pass in the %s method name as a ""keyword argument to %s(). Don't do that."%(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)ifhasattr(self,'get')andnothasattr(self,'head'):self.head=self.getself.request=requestself.args=argsself.kwargs=kwargsreturnself.dispatch(request,*args,**kwargs)# 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

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)

MultipleObjectMixin

defget_context_data(self,**kwargs):""" Get the context for this view. """queryset=kwargs.pop('object_list',self.object_list)page_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(MultipleObjectMixin,self).get_context_data(**context)

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

defget_dated_queryset(self,ordering=None,**lookup):""" Get a queryset properly filtered according to `allow_future` and any extra lookup kwargs. """qs=self.get_queryset().filter(**lookup)date_field=self.get_date_field()allow_future=self.get_allow_future()allow_empty=self.get_allow_empty()paginate_by=self.get_paginate_by(qs)iforderingisnotNone:qs=qs.order_by(ordering)ifnotallow_future:now=timezone.now()ifself.uses_datetime_fieldelsetimezone_today()qs=qs.filter(**{'%s__lte'%date_field:now})ifnotallow_empty:# When pagination is enabled, it's better to do a cheap query# than to load the unpaginated queryset in memory.is_empty=len(qs)==0ifpaginate_byisNoneelsenotqs.exists()ifis_empty:raiseHttp404(_("No %(verbose_name_plural)s available")%{'verbose_name_plural':force_text(qs.model._meta.verbose_name_plural)})returnqs

defget_date_field(self):""" Get the name of the date field to be used to filter by. """ifself.date_fieldisNone:raiseImproperlyConfigured("%s.date_field is required."%self.__class__.__name__)returnself.date_field

defget_date_list(self,queryset,date_type=None,ordering='ASC'):""" Get a date list by calling `queryset.dates/datetimes()`, checking along the way for empty lists that aren't allowed. """date_field=self.get_date_field()allow_empty=self.get_allow_empty()ifdate_typeisNone:date_type=self.get_date_list_period()ifself.uses_datetime_field:date_list=queryset.datetimes(date_field,date_type,ordering)else:date_list=queryset.dates(date_field,date_type,ordering)ifdate_listisnotNoneandnotdate_listandnotallow_empty:name=force_text(queryset.model._meta.verbose_name_plural)raiseHttp404(_("No %(verbose_name_plural)s available")%{'verbose_name_plural':name})returndate_list

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)

Get the list of items for this view. This must be an iterable, and may
be a queryset (in which qs-specific behavior will be enabled).

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

defget_queryset(self):""" Get the list of items for this view. This must be an iterable, and may be a queryset (in which qs-specific behavior will be enabled). """ifself.querysetisnotNone:queryset=self.querysetifhasattr(queryset,'_clone'):queryset=queryset._clone()elifself.modelisnotNone:queryset=self.model._default_manager.all()else:raiseImproperlyConfigured("'%s' must define 'queryset' or 'model'"%self.__class__.__name__)returnqueryset

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(MultipleObjectTemplateResponseMixin,self).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))returnnames

TemplateResponseMixin

Returns 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.

135
136
137
138
139
140
141
142
143
144
145

defget_template_names(self):""" Returns 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]

Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.

36
37
38
39
40
41
42
43
44

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,valueinsix.iteritems(kwargs):setattr(self,key,value)

Convert a date into a datetime when the date field is a DateTimeField.
When time zone support is enabled, `date` is assumed to be in the
current time zone, so that displayed items are consistent with the URL.

292
293
294
295
296
297
298
299
300
301
302

def_make_date_lookup_arg(self,value):""" Convert a date into a datetime when the date field is a DateTimeField. When time zone support is enabled, `date` is assumed to be in the current time zone, so that displayed items are consistent with the URL. """ifself.uses_datetime_field:value=datetime.datetime.combine(value,datetime.time.min)ifsettings.USE_TZ:value=timezone.make_aware(value,timezone.get_current_timezone())returnvalue

Get the lookup kwargs for filtering on a single date.
If the date field is a DateTimeField, we can't just filter on
date_field=date because that doesn't take the time into account.

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321

def_make_single_date_lookup(self,date):""" Get the lookup kwargs for filtering on a single date. If the date field is a DateTimeField, we can't just filter on date_field=date because that doesn't take the time into account. """date_field=self.get_date_field()ifself.uses_datetime_field:since=self._make_date_lookup_arg(date)until=self._make_date_lookup_arg(date+datetime.timedelta(days=1))return{'%s__gte'%date_field:since,'%s__lt'%date_field:until,}else:# Skip self._make_date_lookup_arg, it's a no-op in this branch.return{date_field:date}

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)})

Returns a response, using the `response_class` for this
view, with a template rendered with the given context.
If any keyword arguments are provided, they will be
passed to the constructor of the response class.

119
120
121
122
123
124
125
126
127
128
129
130
131
132

defrender_to_response(self,context,**response_kwargs):""" Returns a response, using the `response_class` for this view, with a template rendered with the given context. If any keyword arguments are provided, they will be passed 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,**response_kwargs)