Skip to main content

Date-Based Archive Navigation

Date-based archive views in this codebase provide a structured way to navigate through objects chronologically. These views, located in django/views/generic/dates.py, allow you to create index pages, yearly summaries, and detailed daily archives with built-in support for time zones and future-dated content filtering.

Core Configuration

All date-based views inherit from DateMixin, which defines the fundamental requirements for filtering by date.

The Date Field

The date_field attribute is mandatory. It specifies which field on the model (either a DateField or DateTimeField) should be used for chronological organization.

class BookArchive(ArchiveIndexView):
model = Book
date_field = "pubdate"

Filtering Behavior

Two key attributes control which objects are included in the archive:

  • allow_future: Defaults to False. If False, the view will exclude objects with a date in the future relative to the current time.
  • allow_empty: Defaults to False. If False, the view raises a 404 error if no objects exist for the given date range.

The Archive Index

The ArchiveIndexView serves as the top-level entry point for an archive. It typically displays the most recent items and a list of years that contain content.

In django/views/generic/dates.py, BaseArchiveIndexView sets the default context_object_name to "latest".

# tests/generic_views/views.py
class BookArchive(generic.ArchiveIndexView):
queryset = Book.objects.all()
date_field = "pubdate"
context_object_name = "latest"

The template (defaulting to book_archive.html) receives:

  • latest: The list of objects (usually the most recent).
  • date_list: A list of years (as datetime.date objects) that have objects.

Chronological Navigation Views

The codebase provides a hierarchy of views for narrowing down the archive by specific time periods.

Year Archive

YearArchiveView displays objects for a specific year. By default, it does not include the full list of objects for that year to avoid performance issues with large datasets; instead, it provides a date_list of months.

To include the objects, set make_object_list = True.

# tests/generic_views/views.py
class BookYearArchive(generic.YearArchiveView):
queryset = Book.objects.all()
date_field = "pubdate"
make_object_list = True

Month and Week Archives

MonthArchiveView and WeekArchiveView filter objects by the specified month or week.

For WeekArchiveView, the week_format determines the start of the week:

  • %U: Week starts on Sunday (default).
  • %W: Week starts on Monday.
# tests/generic_views/views.py
class BookWeekArchive(generic.WeekArchiveView):
queryset = Book.objects.all()
date_field = "pubdate"
week_format = "%W" # Monday start

Day and Today Archives

DayArchiveView filters for a specific day, while TodayArchiveView automatically uses the current date.

# tests/generic_views/views.py
class BookTodayArchive(generic.TodayArchiveView):
queryset = Book.objects.all()
date_field = "pubdate"

URL Configuration and Parameters

These views rely on URL parameters to determine the date range. The YearMixin, MonthMixin, and DayMixin classes extract these from the URL.

Common URL patterns found in tests/generic_views/urls.py:

urlpatterns = [
# Year: /2023/
path("dates/books/<int:year>/", BookYearArchive.as_view()),
# Month: /2023/oct/
path("dates/books/<int:year>/<str:month>/", BookMonthArchive.as_view()),
# Day: /2023/oct/12/
path("dates/books/<int:year>/<str:month>/<int:day>/", BookDayArchive.as_view()),
]

One of the primary features of these views is the automatic calculation of adjacent time periods for navigation. The get_dated_items method in each base class populates the context with "next" and "previous" objects.

ViewContext Variables
YearArchiveViewyear, next_year, previous_year
MonthArchiveViewmonth, next_month, previous_month
WeekArchiveViewweek, next_week, previous_week
DayArchiveViewday, next_day, previous_day, next_month, previous_month

These variables are datetime.date objects. If allow_empty is False, the view will only provide a next or previous link if there is actually content in that period.

Date Detail View

The DateDetailView is a specialized version of DetailView that requires a specific date in the URL in addition to the object's identifier. This is useful for ensuring that a URL like /2023/oct/12/my-post/ only works if "my-post" was actually published on that exact date.

# django/views/generic/dates.py
class DateDetailView(SingleObjectTemplateResponseMixin, BaseDateDetailView):
"""
Detail view of a single object on a single date.
"""
template_name_suffix = "_detail"

It uses _make_single_date_lookup to generate the appropriate query filters, handling the difference between DateField and DateTimeField (where it creates a range lookup for the entire day).