@classonlymethoddefas_view(cls,**initkwargs):""" Main entry point for a request-response process. """forkeyininitkwargs: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

Do the actual heavy lifting of getting the dated items; this accepts a
date object so that TodayArchiveView can be trivial.

596
597
598
599
600
601
602
603
604
605
606
607
608
609

def_get_dated_items(self,date):""" Do the actual heavy lifting of getting the dated items; this accepts a date object so that TodayArchiveView can be trivial. """lookup_kwargs=self._make_single_date_lookup(date)qs=self.get_dated_queryset(**lookup_kwargs)return(None,qs,{'day':date,'previous_day':self.get_previous_day(date),'next_day':self.get_next_day(date),'previous_month':self.get_previous_month(date),'next_month':self.get_next_month(date)})

defget_dated_queryset(self,**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)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_day(self):""" Return the day for which this view should display data. """day=self.dayifdayisNone:try:day=self.kwargs['day']exceptKeyError:try:day=self.request.GET['day']exceptKeyError:raiseHttp404(_("No day specified"))returnday

defget_month(self):""" Return the month for which this view should display data. """month=self.monthifmonthisNone:try:month=self.kwargs['month']exceptKeyError:try:month=self.request.GET['month']exceptKeyError:raiseHttp404(_("No month specified"))returnmonth

Return the start date of the next interval.
The interval is defined by start date <= item date < next start date.

119
120
121
122
123
124
125
126
127

def_get_next_month(self,date):""" Return the start date of the next interval. The interval is defined by start date <= item date < next start date. """ifdate.month==12:returndate.replace(year=date.year+1,month=1,day=1)else:returndate.replace(month=date.month+1,day=1)

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)

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,six.string_types):ordering=(ordering,)queryset=queryset.order_by(*ordering)returnqueryset

defget_year(self):""" Return the year for which this view should display data. """year=self.yearifyearisNone:try:year=self.kwargs['year']exceptKeyError:try:year=self.request.GET['year']exceptKeyError:raiseHttp404(_("No year specified"))returnyear

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

39
40
41
42
43
44
45
46
47

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.

298
299
300
301
302
303
304
305
306
307
308

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.

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

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