o atd@sddlZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZdd lmZdd lmZmZdd lmZmZGd d d ZGdddZGdddZGdddZGdddZGdddeeeZGdddeZGdddeeZGdddeeZ Gdddee Z!Gd d!d!eeeZ"Gd"d#d#ee"Z#Gd$d%d%eeeZ$Gd&d'd'ee$Z%Gd(d)d)eeeeZ&Gd*d+d+ee&Z'Gd,d-d-e&Z(Gd.d/d/ee(Z)Gd0d1d1eeeeeZ*Gd2d3d3ee*Z+dr/r?r@rArBrDrErrrrr=Ds  r=c@r)DayMixinz,Mixin for views manipulating day-based data.z%dNcCr)zt Get a day format string in strptime syntax to be used to parse the day from url variables. ) day_formatrrrrget_day_format}rzDayMixin.get_day_formatc Cr)z7Return the day for which this view should display data.Nr0zNo day specified)r0rrrrrr)rr0rrrget_dayr zDayMixin.get_daycCr!)zGet the next valid day.Fr0r"r%r'rrr get_next_dayr*zDayMixin.get_next_daycCr!)zGet the previous valid day.Tr0r"r%r'rrrget_previous_dayr*zDayMixin.get_previous_daycCs|tjddS)r,r-days)datetime timedeltar'rrr _get_next_dayszDayMixin._get_next_daycCs|Sr5rr'rrr_get_current_dayszDayMixin._get_current_day) r9r:r;r<rGr0rHrIrJrKrPrRrrrrrFxs  rFc@sPeZdZdZdZdZddZddZdd Zd d Z d d Z ddZ ddZ dS) WeekMixinz-Mixin for views manipulating week-based data.%UNcCr)zv Get a week format string in strptime syntax to be used to parse the week from url variables. ) week_formatrrrrget_week_formatrzWeekMixin.get_week_formatc Cr)z8Return the week for which this view should display data.NweekzNo week specified)rWrrrrrr)rrWrrrget_weekr zWeekMixin.get_weekcCr!)zGet the next valid week.FrWr"r%r'rrr get_next_weekr*zWeekMixin.get_next_weekcCr!)zGet the previous valid week.TrWr"r%r'rrrget_previous_weekr*zWeekMixin.get_previous_weekcCs8z|tjd||dWStyttdw)r,rLr1)rNrO _get_weekday OverflowErrorrrr'rrr_get_next_weeks   zWeekMixin._get_next_weekcCs|t||SrQ)rNrOr\r'rrr_get_current_weekszWeekMixin._get_current_weekcCs<|}|dvr |S|dkr|ddStd|)z Return the weekday for a given date. The first day according to the week format is 0 and the last day is 6. >%V%WrTr-r[zunknown week format: %s)rVweekdayr3)rr(rUrrrr\s  zWeekMixin._get_weekday) r9r:r;r<rUrWrVrXrYrZr^r_r\rrrrrSs  rSc@sDeZdZdZdZdZddZddZedd Z d d Z d d Z dS) DateMixinz3Mixin class for views manipulating date-based data.NFcCs |jdur td|jj|jS)z7Get the name of the date field to be used to filter by.Nz%s.date_field is required.) date_fieldr __class__r9rrrrget_date_fields zDateMixin.get_date_fieldcCr)zi Return `True` if the view should be allowed to display objects from the future. ) allow_futurerrrrget_allow_futurerzDateMixin.get_allow_futurecCs6|jdur |jn|j}|j|}t|tjS)zq Return `True` if the date field is a `DateTimeField` and `False` if it's a `DateField`. N)model get_queryset_meta get_fieldrf isinstancer DateTimeField)rrifieldrrruses_datetime_fields zDateMixin.uses_datetime_fieldcCs,|jrtj|tjj}tjrt|}|S)z 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. ) rprNcombinetimeminrUSE_TZr make_aware)rvaluerrr_make_date_lookup_args  zDateMixin._make_date_lookup_argcCsJ|}|jr!||}||tjdd}d||d||iS||iS)z 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. r-rL%s__gte%s__lt)rfrprwrNrO)rr(rdsinceuntilrrr_make_single_date_lookups z"DateMixin._make_single_date_lookup) r9r:r;r<rdrgrfrhrrprwr|rrrrrcs  rcc@sJeZdZdZdZdZddZddZdd Zd d Z d d Z dddZ dS)BaseDateListViewzFAbstract base class for date-based views displaying a list of objects.FrcOs6|\|_|_}|jd|j|jd|}||S)N) object_list date_listr)get_dated_itemsrr~get_context_datarender_to_response)rrargsr extra_contextcontextrrrget*s zBaseDateListView.getcCstd)z#Obtain the list of dates and items.z>A DateView must provide an implementation of get_dated_items())NotImplementedErrorrrrrr3sz BaseDateListView.get_dated_itemscCs|jdur d|S|jS)zu Return the field or fields to use for ordering the queryset; use the date field by default. N-%s)orderingrfrrrr get_ordering7szBaseDateListView.get_orderingc Ks|jdi|}|}|}|}||}|s3|jr$tnt }|jdid||i}|sP|dur<| n| }|rPt t dd|j jji|S)zs Get a queryset properly filtered according to `allow_future` and any extra lookup kwargs. %s__lteN$No %(verbose_name_plural)s availableverbose_name_pluralr)rjfilterrfrhget_allow_emptyget_paginate_byrprnowtimezone_todayexistsrrrirkr) rlookupqsrdrg allow_empty paginate_byris_emptyrrrget_dated_queryset>s  z#BaseDateListView.get_dated_querysetcCr)zf Get the aggregation period for the list of dates: 'year', 'month', or 'day'. )date_list_periodrrrrget_date_list_periodXrz%BaseDateListView.get_date_list_periodNASCcCsr|}|}|dur|}|jr||||}n||||}|dur7|s7|s7ttdd|jj j i|S)z Get a date list by calling `queryset.dates/datetimes()`, checking along the way for empty lists that aren't allowed. Nrr) rfrrrp datetimesdatesrrrirkr)rqueryset date_typerrdrrrrr get_date_list_s zBaseDateListView.get_date_list)Nr) r9r:r;r<rrrrrrrrrrrrr}%s r}c@eZdZdZdZddZdS)BaseArchiveIndexViewzQ Base class for archives of date-based items. Requires a response mixin. latestcCs,|}|j|dd}|s|}||ifS):Return (date_list, items, extra_context) for this request.DESC)r)rrnone)rrrrrrr}s  z$BaseArchiveIndexView.get_dated_itemsN)r9r:r;r<context_object_namerrrrrrws rc@eZdZdZdZdS)ArchiveIndexViewz&Top-level archive of date-based items._archiveNr9r:r;r<template_name_suffixrrrrrrc@s(eZdZdZdZdZddZddZdS) BaseYearArchiveView*List of objects published in a given year.r/Fc Cs|}|}t||}||}|||}d||d||i}|jdi|}||}|s;| }|||| || |dfS)rrxry)r next_year previous_yearNr) rrf_date_from_stringrrwr4rrget_make_object_listrr)r+) rrrdr(rzr{ lookup_kwargsrrrrrrs"  z#BaseYearArchiveView.get_dated_itemscCr)zo Return `True` if this view should contain the full list of objects in the given year. )make_object_listrrrrrrz(BaseYearArchiveView.get_make_object_listN)r9r:r;r<rrrrrrrrrs  rc@r)YearArchiveViewr _archive_yearNrrrrrrrrc@r)BaseMonthArchiveView+List of objects published in a given month.r0c Cs|}|}|}t||||}||}|||}d||d||i}|jdi|}| |} | ||| || |dfS)rrxry)r/ next_monthprevious_monthNr) rr@rfrrr?rwrDrrrArB) rrr/rdr(rzr{rrrrrrrs$   z$BaseMonthArchiveView.get_dated_itemsN)r9r:r;r<rrrrrrrs rc@r)MonthArchiveViewr_archive_monthNrrrrrrrrc@eZdZdZddZdS)BaseWeekArchiveView*List of objects published in a given week.c Cs|}|}|}|}dddd}z||}Wnty0td|dt|fw|}|dkrE|dkrEtd||ft |||d ||}| |} | | |} d || d || i} |j di| } d | || |||d fS)r10)rarTr`z'Unknown week format %r. Choices are: %sz, r`z%GzeISO week directive '%s' is incompatible with the year directive '%s'. Use the ISO year '%%G' instead.z%wrxryN)rW next_week previous_weekr)rrXrfrVrr3joinsortedrrrwr^rrYrZ) rrrWrdrU week_choices week_startrr(rzr{rrrrrrsB     z#BaseWeekArchiveView.get_dated_itemsNr9r:r;r<rrrrrr rc@r)WeekArchiveViewr _archive_weekNrrrrrr rrc@s eZdZdZddZddZdS)BaseDayArchiveView)List of objects published on a given day.cCs@|}|}|}t||||||}||Sr)rr@rIrrr?rH_get_dated_items)rrr/r0r(rrrrs  z"BaseDayArchiveView.get_dated_itemsc CsH||}|jdi|}d||||||||||dfS)z Do the actual heavy lifting of getting the dated items; this accepts a date object so that TodayArchiveView can be trivial. N)r0 previous_daynext_dayrrr)r|rrKrJrBrA)rr(rrrrrrs z#BaseDayArchiveView._get_dated_itemsN)r9r:r;r<rrrrrrrs rc@r)DayArchiveViewr _archive_dayNrrrrrr-rrc@r)BaseTodayArchiveView List of objects published today.cCs|tjSr)rrNr(todayrrrrr5r*z$BaseTodayArchiveView.get_dated_itemsNrrrrrr2rrc@r)TodayArchiveViewrrNrrrrrr:rrcs"eZdZdZdfdd ZZS)BaseDateDetailView 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. Ncs|}|}|}t||||||}|dur#|n|}|s@|t j kr@t t d|jjj|jjd||}|jdi|}tj|dS)z%Get the object this request displays.NzZFuture %(verbose_name_plural)s not available because %(class_name)s.allow_future is False.)r class_name)rr)rr@rIrrr?rHrjrhrNr(rrrrirkrrer9r|rsuper get_object)rrrr/r0r(rrrerrrDs&  zBaseDateDetailView.get_object)N)r9r:r;r<r __classcell__rrrrr?src@r)DateDetailViewr_detailNrrrrrrbsr__c Csn|||||}t||t||t|}z tj||WSty6ttd||dw)z 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. uCInvalid date string “%(datestr)s” given format “%(format)s”)datestrformat)strrNstrptimer(r3rr) rrr/r>r0rGdelimrrrrrrjs   rcCsB|}|}|}t|d|}t|d|}||||} } |r?|r2|| tjdd} n| } |s;| tkr=| SdS|rOd||| i} d|} n d||| i} |} |sm|jrdt }nt}|| d |<| j d i|  | }z t|d |} Wn tyYdSw|jrtjrt | } | } || S) aV 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. z_get_current_%sz _get_next_%sr-rLNryrrxrrr)rfrrhgetattrrNrOrrwrprrrjrorder_by IndexErrorrrt localtimer() generic_viewr(r#r$rdrrg get_currentget_nextstartendresultrrrrrrrr&zsD     r&cCstjrtStjS)z1Return the current date in the current time zone.)rrtr localdaterNr(rrrrrrs r)rrrrr)/rN django.confrdjango.core.exceptionsr django.dbr django.httpr django.utilsrdjango.utils.functionalrdjango.utils.translationrrdjango.views.generic.baser django.views.generic.detailr r django.views.generic.listr r rr=rFrSrcr}rrrrrrrrrrrrrrrr&rrrrrsD        14.?@R)+#  Z