mixin for views manipulating yearbased data yearformat y year none def getyearformatself return self yearformat def getyearself get the next valid year return getnextprevself date ispreviousfalse periodyear def getpreviousyearself date return the start date of the next interval the interval is defined by start date item date next start date return the start date of the current interval return date replacemonth1 day1 class monthmixin get a month format string in strptime syntax to be used to parse the month from url variables return the month for which this view should display data month self month if month is none try month self kwargsmonth except keyerror try month self request getmonth except keyerror raise http404no month specified return month def getnextmonthself date get the previous valid month return getnextprevself date isprevioustrue periodmonth def getnextmonthself date if date month 12 try return date replaceyeardate year 1 month1 day1 except valueerror raise http404date out of range else return date replacemonthdate month 1 day1 def getcurrentmonthself date mixin for views manipulating daybased data dayformat d day none def getdayformatself return self dayformat def getdayself get the next valid day return getnextprevself date ispreviousfalse periodday def getpreviousdayself date return the start date of the next interval the interval is defined by start date item date next start date return the start date of the current interval return date class weekmixin get a week format string in strptime syntax to be used to parse the week from url variables return the week for which this view should display data week self week if week is none try week self kwargsweek except keyerror try week self request getweek except keyerror raise http404no week specified return week def getnextweekself date get the previous valid week return getnextprevself date isprevioustrue periodweek def getnextweekself date try return date datetime timedeltadays7 self getweekdaydate except overflowerror raise http404date out of range def getcurrentweekself date return the weekday for a given date the first day according to the week format is 0 and the last day is 6 mixin class for views manipulating datebased data datefield none allowfuture false def getdatefieldself return true if the view should be allowed to display objects from the future note the following three methods only work in subclasses that also inherit singleobjectmixin or multipleobjectmixin return true if the date field is a datetimefield and false if it s a datefield 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 get the lookup kwargs for filtering on a single date if the date field is a datetimefield we can t just filter on datefielddate because that doesn t take the time into account skip self makedatelookuparg it s a noop in this branch abstract base class for datebased views displaying a list of objects allowempty false datelistperiod year def getself request args kwargs self datelist self objectlist extracontext self getdateditems context self getcontextdata objectlistself objectlist datelistself datelist extracontext return self rendertoresponsecontext def getdateditemsself return the field or fields to use for ordering the queryset use the date field by default get a queryset properly filtered according to allowfuture and any extra lookup kwargs when pagination is enabled it s better to do a cheap query than to load the unpaginated queryset in memory get the aggregation period for the list of dates year month or day get a date list by calling queryset datesdatetimes checking along the way for empty lists that aren t allowed base class for archives of datebased items requires a response mixin return datelist items extracontext for this request qs self getdatedqueryset datelist self getdatelistqs orderingdesc if not datelist qs qs none return datelist qs class archiveindexviewmultipleobjecttemplateresponsemixin basearchiveindexview list of objects published in a given year datelistperiod month makeobjectlist false def getdateditemsself we need this to be a queryset since parent classes introspect it to find information about the model return true if this view should contain the full list of objects in the given year list of objects published in a given year templatenamesuffix archiveyear class basemontharchiveviewyearmixin monthmixin basedatelistview return datelist items extracontext for this request year self getyear month self getmonth datefield self getdatefield date datefromstring year self getyearformat month self getmonthformat since self makedatelookupargdate until self makedatelookupargself getnextmonthdate lookupkwargs sgte datefield since slt datefield until qs self getdatedquerysetlookupkwargs datelist self getdatelistqs return datelist qs month date nextmonth self getnextmonthdate previousmonth self getpreviousmonthdate class montharchiveviewmultipleobjecttemplateresponsemixin basemontharchiveview list of objects published in a given week def getdateditemsself list of objects published in a given week templatenamesuffix archiveweek class basedayarchiveviewyearmixin monthmixin daymixin basedatelistview return datelist items extracontext for this request year self getyear month self getmonth day self getday date datefromstring year self getyearformat month self getmonthformat day self getdayformat return self getdateditemsdate def getdateditemsself date lookupkwargs self makesingledatelookupdate qs self getdatedquerysetlookupkwargs return none qs day date previousday self getpreviousdaydate nextday self getnextdaydate previousmonth self getpreviousmonthdate nextmonth self getnextmonthdate class dayarchiveviewmultipleobjecttemplateresponsemixin basedayarchiveview list of objects published today def getdateditemsself list of objects published today templatenamesuffix archiveday class basedatedetailviewyearmixin monthmixin daymixin datemixin basedetailview def getobjectself querysetnone use a custom queryset if provided filter down a queryset from self queryset using the date from the url this ll get passed as the queryset to detailview getobject which ll handle the 404 detail view of a single object on a single date this differs from the standard detailview by accepting a yearmonthday in the url get a datetime date object given a format string and a year month and day only year is mandatory raise a 404 for an invalid date get the next or the previous valid date the idea is to allow links on monthday views to never be 404s by never providing a date that ll be invalid for the given view this is a bit complicated since it handles different intervals of time hence the coupling to genericview however in essence the logic comes down to if allowempty and allowfuture are both true this is easy just return the naive result just the nextprevious dayweekmonth regardless of object existence if allowempty is true allowfuture is false and the naive result isn t in the future then return it otherwise return none if allowempty is false and allowfuture is true return the next date that contains a valid object even if it s in the future if there are no next objects return none if allowempty is false and allowfuture is false return the next date that contains a valid object if that date is in the future or if there are no next objects return none bounds of the current interval if allowempty is true the naive result will be valid otherwise we ll need to go to the database to look for an object whose datefield is at least greater thanless than the given naive result construct a lookup and an ordering depending on whether we re doing a previous date or a next date lookup filter out objects in the future if appropriate fortunately to match the implementation of allowfuture we need lte which doesn t conflict with lt above snag the first object from the queryset if it doesn t exist that means there s no nextprevious link available convert datetimes to dates in the current time zone return the first day of the period return the current date in the current time zone if settings usetz return timezone localdate else return datetime date today mixin for views manipulating year based data get a year format string in strptime syntax to be used to parse the year from url variables return the year for which this view should display data get the next valid year get the previous valid year return the start date of the next interval the interval is defined by start date item date next start date return the start date of the current interval mixin for views manipulating month based data get a month format string in strptime syntax to be used to parse the month from url variables return the month for which this view should display data get the next valid month get the previous valid month return the start date of the next interval the interval is defined by start date item date next start date return the start date of the previous interval mixin for views manipulating day based data get a day format string in strptime syntax to be used to parse the day from url variables return the day for which this view should display data get the next valid day get the previous valid day return the start date of the next interval the interval is defined by start date item date next start date return the start date of the current interval mixin for views manipulating week based data get a week format string in strptime syntax to be used to parse the week from url variables return the week for which this view should display data get the next valid week get the previous valid week return the start date of the next interval the interval is defined by start date item date next start date return the start date of the current interval return the weekday for a given date the first day according to the week format is 0 and the last day is 6 week starts on monday week starts on sunday mixin class for views manipulating date based data get the name of the date field to be used to filter by return true if the view should be allowed to display objects from the future note the following three methods only work in subclasses that also inherit singleobjectmixin or multipleobjectmixin return true if the date field is a datetimefield and false if it s a datefield 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 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 skip self _make_date_lookup_arg it s a no op in this branch abstract base class for date based views displaying a list of objects obtain the list of dates and items return the field or fields to use for ordering the queryset use the date field by default get a queryset properly filtered according to allow_future and any extra lookup kwargs when pagination is enabled it s better to do a cheap query than to load the unpaginated queryset in memory get the aggregation period for the list of dates year month or day get a date list by calling queryset dates datetimes checking along the way for empty lists that aren t allowed base class for archives of date based items requires a response mixin return date_list items extra_context for this request top level archive of date based items list of objects published in a given year return date_list items extra_context for this request we need this to be a queryset since parent classes introspect it to find information about the model return true if this view should contain the full list of objects in the given year list of objects published in a given year list of objects published in a given month return date_list items extra_context for this request list of objects published in a given month list of objects published in a given week return date_list items extra_context for this request list of objects published in a given week list of objects published on a given day return date_list items extra_context for this request do the actual heavy lifting of getting the dated items this accepts a date object so that todayarchiveview can be trivial list of objects published on a given day list of objects published today return date_list items extra_context for this request list of objects published today detail view of a single object on a single date this differs from the standard detailview by accepting a year month day in the url get the object this request displays use a custom queryset if provided filter down a queryset from self queryset using the date from the url this ll get passed as the queryset to detailview get_object which ll handle the 404 detail view of a single object on a single date this differs from the standard detailview by accepting a year month day in the url get a datetime date object given a format string and a year month and day only year is mandatory raise a 404 for an invalid date get the next or the previous valid date the idea is to allow links on month day views to never be 404s by never providing a date that ll be invalid for the given view this is a bit complicated since it handles different intervals of time hence the coupling to generic_view however in essence the logic comes down to if allow_empty and allow_future are both true this is easy just return the naive result just the next previous day week month regardless of object existence if allow_empty is true allow_future is false and the naive result isn t in the future then return it otherwise return none if allow_empty is false and allow_future is true return the next date that contains a valid object even if it s in the future if there are no next objects return none if allow_empty is false and allow_future is false return the next date that contains a valid object if that date is in the future or if there are no next objects return none bounds of the current interval if allow_empty is true the naive result will be valid otherwise we ll need to go to the database to look for an object whose date_field is at least greater than less than the given naive result construct a lookup and an ordering depending on whether we re doing a previous date or a next date lookup filter out objects in the future if appropriate fortunately to match the implementation of allow_future we need __lte which doesn t conflict with __lt above snag the first object from the queryset if it doesn t exist that means there s no next previous link available convert datetimes to dates in the current time zone return the first day of the period return the current date in the current time zone
import datetime

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.http import Http404
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.translation import gettext as _
from django.views.generic.base import View
from django.views.generic.detail import (
    BaseDetailView,
    SingleObjectTemplateResponseMixin,
)
from django.views.generic.list import (
    MultipleObjectMixin,
    MultipleObjectTemplateResponseMixin,
)


class YearMixin:
    

    year_format = "%Y"
    year = None

    def get_year_format(self):
        
        return self.year_format

    def get_year(self):
        
        year = self.year
        if year is None:
            try:
                year = self.kwargs["year"]
            except KeyError:
                try:
                    year = self.request.GET["year"]
                except KeyError:
                    raise Http404(_("No year specified"))
        return year

    def get_next_year(self, date):
        
        return _get_next_prev(self, date, is_previous=False, period="year")

    def get_previous_year(self, date):
        
        return _get_next_prev(self, date, is_previous=True, period="year")

    def _get_next_year(self, date):
        
        try:
            return date.replace(year=date.year + 1, month=1, day=1)
        except ValueError:
            raise Http404(_("Date out of range"))

    def _get_current_year(self, date):
        
        return date.replace(month=1, day=1)


class MonthMixin:
    

    month_format = "%b"
    month = None

    def get_month_format(self):
        
        return self.month_format

    def get_month(self):
        
        month = self.month
        if month is None:
            try:
                month = self.kwargs["month"]
            except KeyError:
                try:
                    month = self.request.GET["month"]
                except KeyError:
                    raise Http404(_("No month specified"))
        return month

    def get_next_month(self, date):
        
        return _get_next_prev(self, date, is_previous=False, period="month")

    def get_previous_month(self, date):
        
        return _get_next_prev(self, date, is_previous=True, period="month")

    def _get_next_month(self, date):
        
        if date.month == 12:
            try:
                return date.replace(year=date.year + 1, month=1, day=1)
            except ValueError:
                raise Http404(_("Date out of range"))
        else:
            return date.replace(month=date.month + 1, day=1)

    def _get_current_month(self, date):
        
        return date.replace(day=1)


class DayMixin:
    

    day_format = "%d"
    day = None

    def get_day_format(self):
        
        return self.day_format

    def get_day(self):
        
        day = self.day
        if day is None:
            try:
                day = self.kwargs["day"]
            except KeyError:
                try:
                    day = self.request.GET["day"]
                except KeyError:
                    raise Http404(_("No day specified"))
        return day

    def get_next_day(self, date):
        
        return _get_next_prev(self, date, is_previous=False, period="day")

    def get_previous_day(self, date):
        
        return _get_next_prev(self, date, is_previous=True, period="day")

    def _get_next_day(self, date):
        
        return date + datetime.timedelta(days=1)

    def _get_current_day(self, date):
        
        return date


class WeekMixin:
    

    week_format = "%U"
    week = None

    def get_week_format(self):
        
        return self.week_format

    def get_week(self):
        
        week = self.week
        if week is None:
            try:
                week = self.kwargs["week"]
            except KeyError:
                try:
                    week = self.request.GET["week"]
                except KeyError:
                    raise Http404(_("No week specified"))
        return week

    def get_next_week(self, date):
        
        return _get_next_prev(self, date, is_previous=False, period="week")

    def get_previous_week(self, date):
        
        return _get_next_prev(self, date, is_previous=True, period="week")

    def _get_next_week(self, date):
        
        try:
            return date + datetime.timedelta(days=7 - self._get_weekday(date))
        except OverflowError:
            raise Http404(_("Date out of range"))

    def _get_current_week(self, date):
        
        return date - datetime.timedelta(self._get_weekday(date))

    def _get_weekday(self, date):
        
        week_format = self.get_week_format()
        if week_format in {"%W", "%V"}:  
            return date.weekday()
        elif week_format == "%U":  
            return (date.weekday() + 1) % 7
        else:
            raise ValueError("unknown week format: %s" % week_format)


class DateMixin:
    

    date_field = None
    allow_future = False

    def get_date_field(self):
        
        if self.date_field is None:
            raise ImproperlyConfigured(
                "%s.date_field is required." % self.__class__.__name__
            )
        return self.date_field

    def get_allow_future(self):
        
        return self.allow_future

    
    

    @cached_property
    def uses_datetime_field(self):
        
        model = self.get_queryset().model if self.model is None else self.model
        field = model._meta.get_field(self.get_date_field())
        return isinstance(field, models.DateTimeField)

    def _make_date_lookup_arg(self, value):
        
        if self.uses_datetime_field:
            value = datetime.datetime.combine(value, datetime.time.min)
            if settings.USE_TZ:
                value = timezone.make_aware(value)
        return value

    def _make_single_date_lookup(self, date):
        
        date_field = self.get_date_field()
        if self.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:
            
            return {date_field: date}


class BaseDateListView(MultipleObjectMixin, DateMixin, View):
    

    allow_empty = False
    date_list_period = "year"

    def get(self, request, *args, **kwargs):
        self.date_list, self.object_list, extra_context = self.get_dated_items()
        context = self.get_context_data(
            object_list=self.object_list, date_list=self.date_list, **extra_context
        )
        return self.render_to_response(context)

    def get_dated_items(self):
        
        raise NotImplementedError(
            "A DateView must provide an implementation of get_dated_items()"
        )

    def get_ordering(self):
        
        return "-%s" % self.get_date_field() if self.ordering is None else self.ordering

    def get_dated_queryset(self, **lookup):
        
        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)

        if not allow_future:
            now = timezone.now() if self.uses_datetime_field else timezone_today()
            qs = qs.filter(**{"%s__lte" % date_field: now})

        if not allow_empty:
            
            
            is_empty = not qs if paginate_by is None else not qs.exists()
            if is_empty:
                raise Http404(
                    _("No %(verbose_name_plural)s available")
                    % {
                        "verbose_name_plural": qs.model._meta.verbose_name_plural,
                    }
                )

        return qs

    def get_date_list_period(self):
        
        return self.date_list_period

    def get_date_list(self, queryset, date_type=None, ordering="ASC"):
        
        date_field = self.get_date_field()
        allow_empty = self.get_allow_empty()
        if date_type is None:
            date_type = self.get_date_list_period()

        if self.uses_datetime_field:
            date_list = queryset.datetimes(date_field, date_type, ordering)
        else:
            date_list = queryset.dates(date_field, date_type, ordering)
        if date_list is not None and not date_list and not allow_empty:
            raise Http404(
                _("No %(verbose_name_plural)s available")
                % {
                    "verbose_name_plural": queryset.model._meta.verbose_name_plural,
                }
            )

        return date_list


class BaseArchiveIndexView(BaseDateListView):
    

    context_object_name = "latest"

    def get_dated_items(self):
        
        qs = self.get_dated_queryset()
        date_list = self.get_date_list(qs, ordering="DESC")

        if not date_list:
            qs = qs.none()

        return (date_list, qs, {})


class ArchiveIndexView(MultipleObjectTemplateResponseMixin, BaseArchiveIndexView):
    

    template_name_suffix = "_archive"


class BaseYearArchiveView(YearMixin, BaseDateListView):
    

    date_list_period = "month"
    make_object_list = False

    def get_dated_items(self):
        
        year = self.get_year()

        date_field = self.get_date_field()
        date = _date_from_string(year, self.get_year_format())

        since = self._make_date_lookup_arg(date)
        until = self._make_date_lookup_arg(self._get_next_year(date))
        lookup_kwargs = {
            "%s__gte" % date_field: since,
            "%s__lt" % date_field: until,
        }

        qs = self.get_dated_queryset(**lookup_kwargs)
        date_list = self.get_date_list(qs)

        if not self.get_make_object_list():
            
            
            qs = qs.none()

        return (
            date_list,
            qs,
            {
                "year": date,
                "next_year": self.get_next_year(date),
                "previous_year": self.get_previous_year(date),
            },
        )

    def get_make_object_list(self):
        
        return self.make_object_list


class YearArchiveView(MultipleObjectTemplateResponseMixin, BaseYearArchiveView):
    

    template_name_suffix = "_archive_year"


class BaseMonthArchiveView(YearMixin, MonthMixin, BaseDateListView):
    

    date_list_period = "day"

    def get_dated_items(self):
        
        year = self.get_year()
        month = self.get_month()

        date_field = self.get_date_field()
        date = _date_from_string(
            year, self.get_year_format(), month, self.get_month_format()
        )

        since = self._make_date_lookup_arg(date)
        until = self._make_date_lookup_arg(self._get_next_month(date))
        lookup_kwargs = {
            "%s__gte" % date_field: since,
            "%s__lt" % date_field: until,
        }

        qs = self.get_dated_queryset(**lookup_kwargs)
        date_list = self.get_date_list(qs)

        return (
            date_list,
            qs,
            {
                "month": date,
                "next_month": self.get_next_month(date),
                "previous_month": self.get_previous_month(date),
            },
        )


class MonthArchiveView(MultipleObjectTemplateResponseMixin, BaseMonthArchiveView):
    

    template_name_suffix = "_archive_month"


class BaseWeekArchiveView(YearMixin, WeekMixin, BaseDateListView):
    

    def get_dated_items(self):
        
        year = self.get_year()
        week = self.get_week()

        date_field = self.get_date_field()
        week_format = self.get_week_format()
        week_choices = {"%W": "1", "%U": "0", "%V": "1"}
        try:
            week_start = week_choices[week_format]
        except KeyError:
            raise ValueError(
                "Unknown week format %r. Choices are: %s"
                % (
                    week_format,
                    ", ".join(sorted(week_choices)),
                )
            )
        year_format = self.get_year_format()
        if week_format == "%V" and year_format != "%G":
            raise ValueError(
                "ISO week directive '%s' is incompatible with the year "
                "directive '%s'. Use the ISO year '%%G' instead."
                % (
                    week_format,
                    year_format,
                )
            )
        date = _date_from_string(year, year_format, week_start, "%w", week, week_format)
        since = self._make_date_lookup_arg(date)
        until = self._make_date_lookup_arg(self._get_next_week(date))
        lookup_kwargs = {
            "%s__gte" % date_field: since,
            "%s__lt" % date_field: until,
        }

        qs = self.get_dated_queryset(**lookup_kwargs)

        return (
            None,
            qs,
            {
                "week": date,
                "next_week": self.get_next_week(date),
                "previous_week": self.get_previous_week(date),
            },
        )


class WeekArchiveView(MultipleObjectTemplateResponseMixin, BaseWeekArchiveView):
    

    template_name_suffix = "_archive_week"


class BaseDayArchiveView(YearMixin, MonthMixin, DayMixin, BaseDateListView):
    

    def get_dated_items(self):
        
        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(),
        )

        return self._get_dated_items(date)

    def _get_dated_items(self, date):
        
        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),
            },
        )


class DayArchiveView(MultipleObjectTemplateResponseMixin, BaseDayArchiveView):
    

    template_name_suffix = "_archive_day"


class BaseTodayArchiveView(BaseDayArchiveView):
    

    def get_dated_items(self):
        
        return self._get_dated_items(datetime.date.today())


class TodayArchiveView(MultipleObjectTemplateResponseMixin, BaseTodayArchiveView):
    

    template_name_suffix = "_archive_day"


class BaseDateDetailView(YearMixin, MonthMixin, DayMixin, DateMixin, BaseDetailView):
    

    def get_object(self, queryset=None):
        
        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(),
        )

        
        qs = self.get_queryset() if queryset is None else queryset

        if not self.get_allow_future() and date > datetime.date.today():
            raise Http404(
                _(
                    "Future %(verbose_name_plural)s not available because "
                    "%(class_name)s.allow_future is False."
                )
                % {
                    "verbose_name_plural": qs.model._meta.verbose_name_plural,
                    "class_name": self.__class__.__name__,
                }
            )

        
        
        
        lookup_kwargs = self._make_single_date_lookup(date)
        qs = qs.filter(**lookup_kwargs)

        return super().get_object(queryset=qs)


class DateDetailView(SingleObjectTemplateResponseMixin, BaseDateDetailView):
    

    template_name_suffix = "_detail"


def _date_from_string(
    year, year_format, month="", month_format="", day="", day_format="", delim="__"
):
    
    format = year_format + delim + month_format + delim + day_format
    datestr = str(year) + delim + str(month) + delim + str(day)
    try:
        return datetime.datetime.strptime(datestr, format).date()
    except ValueError:
        raise Http404(
            _("Invalid date string “%(datestr)s” given format “%(format)s”")
            % {
                "datestr": datestr,
                "format": format,
            }
        )


def _get_next_prev(generic_view, date, is_previous, period):
    
    date_field = generic_view.get_date_field()
    allow_empty = generic_view.get_allow_empty()
    allow_future = generic_view.get_allow_future()

    get_current = getattr(generic_view, "_get_current_%s" % period)
    get_next = getattr(generic_view, "_get_next_%s" % period)

    
    start, end = get_current(date), get_next(date)

    
    if allow_empty:
        if is_previous:
            result = get_current(start - datetime.timedelta(days=1))
        else:
            result = end

        if allow_future or result <= timezone_today():
            return result
        else:
            return None

    
    
    
    else:
        
        
        if is_previous:
            lookup = {"%s__lt" % date_field: generic_view._make_date_lookup_arg(start)}
            ordering = "-%s" % date_field
        else:
            lookup = {"%s__gte" % date_field: generic_view._make_date_lookup_arg(end)}
            ordering = date_field

        
        if not allow_future:
            
            
            if generic_view.uses_datetime_field:
                now = timezone.now()
            else:
                now = timezone_today()
            lookup["%s__lte" % date_field] = now

        qs = generic_view.get_queryset().filter(**lookup).order_by(ordering)

        
        
        try:
            result = getattr(qs[0], date_field)
        except IndexError:
            return None

        
        if generic_view.uses_datetime_field:
            if settings.USE_TZ:
                result = timezone.localtime(result)
            result = result.date()

        
        return get_current(result)


def timezone_today():
    
    if settings.USE_TZ:
        return timezone.localdate()
    else:
        return datetime.date.today()