Skip to content

Commit

Permalink
Fixed #2433 -- Added allow_future option to date-based generic views
Browse files Browse the repository at this point in the history
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3457 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
adrianholovaty committed Jul 27, 2006
1 parent c37a6fa commit ecdd6ae
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 25 deletions.
57 changes: 38 additions & 19 deletions django/views/generic/date_based.py
Expand Up @@ -7,7 +7,7 @@
def archive_index(request, queryset, date_field, num_latest=15,
template_name=None, template_loader=loader,
extra_context=None, allow_empty=False, context_processors=None,
mimetype=None):
mimetype=None, allow_future=False):
"""
Generic top-level archive of date-based objects.
Expand All @@ -20,7 +20,8 @@ def archive_index(request, queryset, date_field, num_latest=15,
"""
if extra_context is None: extra_context = {}
model = queryset.model
queryset = queryset.filter(**{'%s__lte' % date_field: datetime.datetime.now()})
if not allow_future:
queryset = queryset.filter(**{'%s__lte' % date_field: datetime.datetime.now()})
date_list = queryset.dates(date_field, 'year')[::-1]
if not date_list and not allow_empty:
raise Http404, "No %s available" % model._meta.verbose_name
Expand All @@ -47,7 +48,7 @@ def archive_index(request, queryset, date_field, num_latest=15,
def archive_year(request, year, queryset, date_field, template_name=None,
template_loader=loader, extra_context=None, allow_empty=False,
context_processors=None, template_object_name='object', mimetype=None,
make_object_list=False):
make_object_list=False, allow_future=False):
"""
Generic yearly archive view.
Expand All @@ -67,8 +68,8 @@ def archive_year(request, year, queryset, date_field, template_name=None,

lookup_kwargs = {'%s__year' % date_field: year}

# Only bother to check current date if the year isn't in the past.
if int(year) >= now.year:
# Only bother to check current date if the year isn't in the past and future objects aren't requested.
if int(year) >= now.year and not allow_future:
lookup_kwargs['%s__lte' % date_field] = now
date_list = queryset.filter(**lookup_kwargs).dates(date_field, 'month')
if not date_list and not allow_empty:
Expand All @@ -95,7 +96,7 @@ def archive_year(request, year, queryset, date_field, template_name=None,
def archive_month(request, year, month, queryset, date_field,
month_format='%b', template_name=None, template_loader=loader,
extra_context=None, allow_empty=False, context_processors=None,
template_object_name='object', mimetype=None):
template_object_name='object', mimetype=None, allow_future=False):
"""
Generic monthly archive view.
Expand Down Expand Up @@ -127,19 +128,28 @@ def archive_month(request, year, month, queryset, date_field,
last_day = first_day.replace(month=first_day.month + 1)
lookup_kwargs = {'%s__range' % date_field: (first_day, last_day)}

# Only bother to check current date if the month isn't in the past.
if last_day >= now.date():
# Only bother to check current date if the month isn't in the past and future objects are requested.
if last_day >= now.date() and not allow_future:
lookup_kwargs['%s__lte' % date_field] = now
object_list = queryset.filter(**lookup_kwargs)
if not object_list and not allow_empty:
raise Http404

# Calculate the next month, if applicable.
if allow_future:
next_month = last_day + datetime.timedelta(days=1)
elif last_day < datetime.date.today():
next_month = last_day + datetime.timedelta(days=1)
else:
next_month = None

if not template_name:
template_name = "%s/%s_archive_month.html" % (model._meta.app_label, model._meta.object_name.lower())
t = template_loader.get_template(template_name)
c = RequestContext(request, {
'%s_list' % template_object_name: object_list,
'month': date,
'next_month': (last_day < datetime.date.today()) and (last_day + datetime.timedelta(days=1)) or None,
'next_month': next_month,
'previous_month': first_day - datetime.timedelta(days=1),
}, context_processors)
for key, value in extra_context.items():
Expand All @@ -152,7 +162,7 @@ def archive_month(request, year, month, queryset, date_field,
def archive_week(request, year, week, queryset, date_field,
template_name=None, template_loader=loader,
extra_context=None, allow_empty=True, context_processors=None,
template_object_name='object', mimetype=None):
template_object_name='object', mimetype=None, allow_future=False):
"""
Generic weekly archive view.
Expand All @@ -177,8 +187,8 @@ def archive_week(request, year, week, queryset, date_field,
last_day = date + datetime.timedelta(days=7)
lookup_kwargs = {'%s__range' % date_field: (first_day, last_day)}

# Only bother to check current date if the week isn't in the past.
if last_day >= now.date():
# Only bother to check current date if the week isn't in the past and future objects aren't requested.
if last_day >= now.date() and not allow_future:
lookup_kwargs['%s__lte' % date_field] = now
object_list = queryset.filter(**lookup_kwargs)
if not object_list and not allow_empty:
Expand All @@ -201,7 +211,7 @@ def archive_day(request, year, month, day, queryset, date_field,
month_format='%b', day_format='%d', template_name=None,
template_loader=loader, extra_context=None, allow_empty=False,
context_processors=None, template_object_name='object',
mimetype=None):
mimetype=None, allow_future=False):
"""
Generic daily archive view.
Expand Down Expand Up @@ -229,20 +239,29 @@ def archive_day(request, year, month, day, queryset, date_field,
'%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max)),
}

# Only bother to check current date if the date isn't in the past.
if date >= now.date():
# Only bother to check current date if the date isn't in the past and future objects aren't requested.
if date >= now.date() and not allow_future:
lookup_kwargs['%s__lte' % date_field] = now
object_list = queryset.filter(**lookup_kwargs)
if not allow_empty and not object_list:
raise Http404

# Calculate the next day, if applicable.
if allow_future:
next_day = date + datetime.timedelta(days=1)
elif date < datetime.date.today():
next_day = date + datetime.timedelta(days=1)
else:
next_day = None

if not template_name:
template_name = "%s/%s_archive_day.html" % (model._meta.app_label, model._meta.object_name.lower())
t = template_loader.get_template(template_name)
c = RequestContext(request, {
'%s_list' % template_object_name: object_list,
'day': date,
'previous_day': date - datetime.timedelta(days=1),
'next_day': (date < datetime.date.today()) and (date + datetime.timedelta(days=1)) or None,
'next_day': next_day,
}, context_processors)
for key, value in extra_context.items():
if callable(value):
Expand All @@ -267,7 +286,7 @@ def object_detail(request, year, month, day, queryset, date_field,
month_format='%b', day_format='%d', object_id=None, slug=None,
slug_field=None, template_name=None, template_name_field=None,
template_loader=loader, extra_context=None, context_processors=None,
template_object_name='object', mimetype=None):
template_object_name='object', mimetype=None, allow_future=False):
"""
Generic detail view from year/month/day/slug or year/month/day/id structure.
Expand All @@ -289,8 +308,8 @@ def object_detail(request, year, month, day, queryset, date_field,
'%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max)),
}

# Only bother to check current date if the date isn't in the past.
if date >= now.date():
# Only bother to check current date if the date isn't in the past and future objects aren't requested.
if date >= now.date() and not allow_future:
lookup_kwargs['%s__lte' % date_field] = now
if object_id:
lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
Expand Down
48 changes: 42 additions & 6 deletions docs/generic_views.txt
Expand Up @@ -148,7 +148,8 @@ are views for displaying drilldown pages for date-based data.
**Description:**

A top-level index page showing the "latest" objects, by date. Objects with
a date in the *future* are not included.
a date in the *future* are not included unless you set ``allow_future`` to
``True``.

**Required arguments:**

Expand Down Expand Up @@ -185,6 +186,11 @@ a date in the *future* are not included.
* ``mimetype``: The MIME type to use for the resulting document. Defaults
to the value of the ``DEFAULT_MIME_TYPE`` setting.

* ``allow_future``: A boolean specifying whether to include "future"
objects on this page, where "future" means objects in which the field
specified in ``date_field`` is greater than the current date/time. By
default, this is ``False``.

**Template name:**

If ``template_name`` isn't specified, this view will use the template
Expand Down Expand Up @@ -217,7 +223,8 @@ In addition to ``extra_context``, the template's context will be:
**Description:**

A yearly archive page showing all available months in a given year. Objects
with a date in the *future* are not displayed.
with a date in the *future* are not displayed unless you set ``allow_future``
to ``True``.

**Required arguments:**

Expand Down Expand Up @@ -265,6 +272,11 @@ with a date in the *future* are not displayed.
* ``mimetype``: The MIME type to use for the resulting document. Defaults
to the value of the ``DEFAULT_MIME_TYPE`` setting.

* ``allow_future``: A boolean specifying whether to include "future"
objects on this page, where "future" means objects in which the field
specified in ``date_field`` is greater than the current date/time. By
default, this is ``False``.

**Template name:**

If ``template_name`` isn't specified, this view will use the template
Expand Down Expand Up @@ -296,7 +308,8 @@ In addition to ``extra_context``, the template's context will be:
**Description:**

A monthly archive page showing all objects in a given month. Objects with a
date in the *future* are not displayed.
date in the *future* are not displayed unless you set ``allow_future`` to
``True``.

**Required arguments:**

Expand Down Expand Up @@ -346,6 +359,11 @@ date in the *future* are not displayed.
* ``mimetype``: The MIME type to use for the resulting document. Defaults
to the value of the ``DEFAULT_MIME_TYPE`` setting.

* ``allow_future``: A boolean specifying whether to include "future"
objects on this page, where "future" means objects in which the field
specified in ``date_field`` is greater than the current date/time. By
default, this is ``False``.

**Template name:**

If ``template_name`` isn't specified, this view will use the template
Expand Down Expand Up @@ -378,7 +396,7 @@ In addition to ``extra_context``, the template's context will be:
**Description:**

A weekly archive page showing all objects in a given week. Objects with a date
in the *future* are not displayed.
in the *future* are not displayed unless you set ``allow_future`` to ``True``.

**Required arguments:**

Expand Down Expand Up @@ -422,6 +440,11 @@ in the *future* are not displayed.
* ``mimetype``: The MIME type to use for the resulting document. Defaults
to the value of the ``DEFAULT_MIME_TYPE`` setting.

* ``allow_future``: A boolean specifying whether to include "future"
objects on this page, where "future" means objects in which the field
specified in ``date_field`` is greater than the current date/time. By
default, this is ``False``.

**Template name:**

If ``template_name`` isn't specified, this view will use the template
Expand All @@ -445,7 +468,8 @@ In addition to ``extra_context``, the template's context will be:
**Description:**

A day archive page showing all objects in a given day. Days in the future throw
a 404 error, regardless of whether any objects exist for future days.
a 404 error, regardless of whether any objects exist for future days, unless
you set ``allow_future`` to ``True``.

**Required arguments:**

Expand Down Expand Up @@ -501,6 +525,11 @@ a 404 error, regardless of whether any objects exist for future days.
* ``mimetype``: The MIME type to use for the resulting document. Defaults
to the value of the ``DEFAULT_MIME_TYPE`` setting.

* ``allow_future``: A boolean specifying whether to include "future"
objects on this page, where "future" means objects in which the field
specified in ``date_field`` is greater than the current date/time. By
default, this is ``False``.

**Template name:**

If ``template_name`` isn't specified, this view will use the template
Expand Down Expand Up @@ -537,7 +566,9 @@ and today's date is used instead.

**Description:**

A page representing an individual object.
A page representing an individual object. If the object has a date value in the
future, the view will throw a 404 error by default, unless you set
``allow_future`` to ``True``.

**Required arguments:**

Expand Down Expand Up @@ -604,6 +635,11 @@ A page representing an individual object.
* ``mimetype``: The MIME type to use for the resulting document. Defaults
to the value of the ``DEFAULT_MIME_TYPE`` setting.

* ``allow_future``: A boolean specifying whether to include "future"
objects on this page, where "future" means objects in which the field
specified in ``date_field`` is greater than the current date/time. By
default, this is ``False``.

**Template name:**

If ``template_name`` isn't specified, this view will use the template
Expand Down

0 comments on commit ecdd6ae

Please sign in to comment.