@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)
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
Return `True` if the view should be allowed to display objects from
the future.
240
241
242
243
244
245
defget_allow_future(self):""" Return `True` if the view should be allowed to display objects from the future. """returnself.allow_future
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
BaseDayArchiveView
Return (date_list, items, extra_context) for this request.
528
529
530
531
532
533
534
535
536
defget_dated_items(self):"""Return (date_list, items, extra_context) for this request."""year=self.get_year()month=self.get_month()day=self.get_day()date=_date_from_string(year,self.get_year_format(),month,self.get_month_format(),day,self.get_day_format())returnself._get_dated_items(date)
BaseDateListView
Obtain the list of dates and items.
307
308
309
defget_dated_items(self):"""Obtain the list of dates and items."""raiseNotImplementedError('A DateView must provide an implementation of get_dated_items()')
Get a queryset properly filtered according to `allow_future` and any
extra lookup kwargs.
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=notqsifpaginate_byisNoneelsenotqs.exists()ifis_empty:raiseHttp404(_("No %(verbose_name_plural)s available")%{'verbose_name_plural':qs.model._meta.verbose_name_plural,})returnqs
Get the name of the date field to be used to filter by.
234
235
236
237
238
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
Get a date list by calling `queryset.dates/datetimes()`, checking
along the way for empty lists that aren't allowed.
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:raiseHttp404(_("No %(verbose_name_plural)s available")%{'verbose_name_plural':queryset.model._meta.verbose_name_plural,})returndate_list
Get the aggregation period for the list of dates: 'year', 'month', or
'day'.
344
345
346
347
348
349
defget_date_list_period(self):""" Get the aggregation period for the list of dates: 'year', 'month', or 'day'. """returnself.date_list_period
Return the day for which this view should display data.
132
133
134
135
136
137
138
139
140
141
142
143
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
Get a day format string in strptime syntax to be used to parse the day
from url variables.
125
126
127
128
129
130
defget_day_format(self):""" Get a day format string in strptime syntax to be used to parse the day from url variables. """returnself.day_format
Return the month for which this view should display data.
80
81
82
83
84
85
86
87
88
89
90
91
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
Get a month format string in strptime syntax to be used to parse the
month from url variables.
73
74
75
76
77
78
defget_month_format(self):""" Get a month format string in strptime syntax to be used to parse the month from url variables. """returnself.month_format
Get the next valid day.
145
146
147
defget_next_day(self,date):"""Get the next valid day."""return_get_next_prev(self,date,is_previous=False,period='day')
Get the next valid month.
93
94
95
defget_next_month(self,date):"""Get the next valid month."""return_get_next_prev(self,date,is_previous=False,period='month')
Get the next valid year.
44
45
46
defget_next_year(self,date):"""Get the next valid year."""return_get_next_prev(self,date,is_previous=False,period='year')
BaseDateListView
Return the field or fields to use for ordering the queryset; use the
date field by default.
311
312
313
314
315
316
defget_ordering(self):""" Return the field or fields to use for ordering the queryset; use the date field by default. """return'-%s'%self.get_date_field()ifself.orderingisNoneelseself.ordering
MultipleObjectMixin
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)
Get the previous valid day.
149
150
151
defget_previous_day(self,date):"""Get the previous valid day."""return_get_next_prev(self,date,is_previous=True,period='day')
Get the previous valid month.
97
98
99
defget_previous_month(self,date):"""Get the previous valid month."""return_get_next_prev(self,date,is_previous=True,period='month')
Get the previous valid year.
48
49
50
defget_previous_year(self,date):"""Get the previous valid year."""return_get_next_prev(self,date,is_previous=True,period='year')
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]
Return the year for which this view should display data.
31
32
33
34
35
36
37
38
39
40
41
42
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
Get a year format string in strptime syntax to be used to parse the
year from url variables.
24
25
26
27
28
29
defget_year_format(self):""" Get a year format string in strptime syntax to be used to parse the year from url variables. """returnself.year_format
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
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)})
Return the start date of the next interval.
The interval is defined by start date <= item date < next start date.
153
154
155
156
157
158
def_get_next_day(self,date):""" Return the start date of the next interval. The interval is defined by start date <= item date < next start date. """returndate+datetime.timedelta(days=1)
Return the start date of the next interval.
The interval is defined by start date <= item date < next start date.
101
102
103
104
105
106
107
108
109
110
111
112
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:try:returndate.replace(year=date.year+1,month=1,day=1)exceptValueError:raiseHttp404(_("Date out of range"))else:returndate.replace(month=date.month+1,day=1)
Return the start date of the next interval.
The interval is defined by start date <= item date < next start date.
52
53
54
55
56
57
58
59
60
def_get_next_year(self,date):""" Return the start date of the next interval. The interval is defined by start date <= item date < next start date. """try:returndate.replace(year=date.year+1,month=1,day=1)exceptValueError:raiseHttp404(_("Date out of range"))
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.
260
261
262
263
264
265
266
267
268
269
270
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)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.
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}
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)