3
(hd                 @   s,  d dl mZ d dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZmZ d dlmZmZ G dd deZG dd deZG dd deZ G dd deZ!G dd deZ"G dd dee"eZ#G dd de#Z$G dd dee$Z%G dd dee#Z&G d d! d!ee&Z'G d"d# d#eee#Z(G d$d% d%ee(Z)G d&d' d'ee!e#Z*G d(d) d)ee*Z+G d*d+ d+eee e#Z,G d,d- d-ee,Z-G d.d/ d/e,Z.G d0d1 d1ee.Z/G d2d3 d3eee e"eZ0G d4d5 d5ee0Z1d>d8d9Z2d:d; Z3d<d= Z4dS )?    )unicode_literalsN)settings)ImproperlyConfigured)models)Http404)timezone)	force_str
force_text)cached_property)ugettext)View)BaseDetailView!SingleObjectTemplateResponseMixin)MultipleObjectMixin#MultipleObjectTemplateResponseMixinc               @   sH   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
dd ZdS )	YearMixinz7
    Mixin for views manipulating year-based data.
    z%YNc             C   s   | j S )zv
        Get a year format string in strptime syntax to be used to parse the
        year from url variables.
        )year_format)self r   >/tmp/pip-install-q3hcpn_q/Django/django/views/generic/dates.pyget_year_format   s    zYearMixin.get_year_formatc             C   sh   | j }|dkrdy| jd }W nF tk
rb   y| jjd }W n  tk
r\   ttdY nX Y nX |S )zJ
        Return the year for which this view should display data.
        NyearzNo year specified)r   kwargsKeyErrorrequestGETr   _)r   r   r   r   r   get_year$   s    zYearMixin.get_yearc             C   s   t | |dddS )z*
        Get the next valid year.
        Fr   )is_previousperiod)_get_next_prev)r   dater   r   r   get_next_year3   s    zYearMixin.get_next_yearc             C   s   t | |dddS )z.
        Get the previous valid year.
        Tr   )r   r   )r    )r   r!   r   r   r   get_previous_year9   s    zYearMixin.get_previous_yearc             C   s   |j |jd dddS )z
        Return the start date of the next interval.

        The interval is defined by start date <= item date < next start date.
           )r   monthday)replacer   )r   r!   r   r   r   _get_next_year?   s    zYearMixin._get_next_yearc             C   s   |j dddS )z@
        Return the start date of the current interval.
        r$   )r%   r&   )r'   )r   r!   r   r   r   _get_current_yearG   s    zYearMixin._get_current_year)__name__
__module____qualname____doc__r   r   r   r   r"   r#   r(   r)   r   r   r   r   r      s   r   c               @   sH   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
dd ZdS )
MonthMixinz8
    Mixin for views manipulating month-based data.
    z%bNc             C   s   | j S )zx
        Get a month format string in strptime syntax to be used to parse the
        month from url variables.
        )month_format)r   r   r   r   get_month_formatU   s    zMonthMixin.get_month_formatc             C   sh   | j }|dkrdy| jd }W nF tk
rb   y| jjd }W n  tk
r\   ttdY nX Y nX |S )zK
        Return the month for which this view should display data.
        Nr%   zNo month specified)r%   r   r   r   r   r   r   )r   r%   r   r   r   	get_month\   s    zMonthMixin.get_monthc             C   s   t | |dddS )z+
        Get the next valid month.
        Fr%   )r   r   )r    )r   r!   r   r   r   get_next_monthk   s    zMonthMixin.get_next_monthc             C   s   t | |dddS )z/
        Get the previous valid month.
        Tr%   )r   r   )r    )r   r!   r   r   r   get_previous_monthq   s    zMonthMixin.get_previous_monthc             C   s8   |j dkr |j|jd dddS |j|j d ddS dS )z
        Return the start date of the next interval.

        The interval is defined by start date <= item date < next start date.
           r$   )r   r%   r&   )r%   r&   N)r%   r'   r   )r   r!   r   r   r   _get_next_monthw   s    
zMonthMixin._get_next_monthc             C   s   |j ddS )zA
        Return the start date of the previous interval.
        r$   )r&   )r'   )r   r!   r   r   r   _get_current_month   s    zMonthMixin._get_current_month)r*   r+   r,   r-   r/   r%   r0   r1   r2   r3   r5   r6   r   r   r   r   r.   N   s   r.   c               @   sH   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
dd ZdS )DayMixinz6
    Mixin for views manipulating day-based data.
    z%dNc             C   s   | j S )zt
        Get a day format string in strptime syntax to be used to parse the day
        from url variables.
        )
day_format)r   r   r   r   get_day_format   s    zDayMixin.get_day_formatc             C   sh   | j }|dkrdy| jd }W nF tk
rb   y| jjd }W n  tk
r\   ttdY nX Y nX |S )zI
        Return the day for which this view should display data.
        Nr&   zNo day specified)r&   r   r   r   r   r   r   )r   r&   r   r   r   get_day   s    zDayMixin.get_dayc             C   s   t | |dddS )z)
        Get the next valid day.
        Fr&   )r   r   )r    )r   r!   r   r   r   get_next_day   s    zDayMixin.get_next_dayc             C   s   t | |dddS )z-
        Get the previous valid day.
        Tr&   )r   r   )r    )r   r!   r   r   r   get_previous_day   s    zDayMixin.get_previous_dayc             C   s   |t jdd S )z
        Return the start date of the next interval.

        The interval is defined by start date <= item date < next start date.
        r$   )days)datetime	timedelta)r   r!   r   r   r   _get_next_day   s    zDayMixin._get_next_dayc             C   s   |S )z@
        Return the start date of the current interval.
        r   )r   r!   r   r   r   _get_current_day   s    zDayMixin._get_current_day)r*   r+   r,   r-   r8   r&   r9   r:   r;   r<   r@   rA   r   r   r   r   r7      s   r7   c               @   sP   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd ZdS )	WeekMixinz7
    Mixin for views manipulating week-based data.
    z%UNc             C   s   | j S )zv
        Get a week format string in strptime syntax to be used to parse the
        week from url variables.
        )week_format)r   r   r   r   get_week_format   s    zWeekMixin.get_week_formatc             C   sh   | j }|dkrdy| jd }W nF tk
rb   y| jjd }W n  tk
r\   ttdY nX Y nX |S )zI
        Return the week for which this view should display data
        NweekzNo week specified)rE   r   r   r   r   r   r   )r   rE   r   r   r   get_week   s    zWeekMixin.get_weekc             C   s   t | |dddS )z*
        Get the next valid week.
        FrE   )r   r   )r    )r   r!   r   r   r   get_next_week   s    zWeekMixin.get_next_weekc             C   s   t | |dddS )z.
        Get the previous valid week.
        TrE   )r   r   )r    )r   r!   r   r   r   get_previous_week   s    zWeekMixin.get_previous_weekc             C   s   |t jd| j| d S )z
        Return the start date of the next interval.

        The interval is defined by start date <= item date < next start date.
           )r=   )r>   r?   _get_weekday)r   r!   r   r   r   _get_next_week   s    zWeekMixin._get_next_weekc             C   s   |t j| j| S )z@
        Return the start date of the current interval.
        )r>   r?   rJ   )r   r!   r   r   r   _get_current_week   s    zWeekMixin._get_current_weekc             C   s@   | j  }|dkr|j S |dkr0|j d d S td| dS )z
        Return the weekday for a given date.

        The first day according to the week format is 0 and the last day is 6.
        z%Wz%Ur$   rI   zunknown week format: %sN)rD   weekday
ValueError)r   r!   rC   r   r   r   rJ      s    zWeekMixin._get_weekday)r*   r+   r,   r-   rC   rE   rD   rF   rG   rH   rK   rL   rJ   r   r   r   r   rB      s   rB   c               @   sD   e Zd ZdZdZdZdd Zdd Zedd	 Z	d
d Z
dd ZdS )	DateMixinz=
    Mixin class for views manipulating date-based data.
    NFc             C   s    | j dkrtd| jj | j S )zI
        Get the name of the date field to be used to filter by.
        Nz%s.date_field is required.)
date_fieldr   	__class__r*   )r   r   r   r   get_date_field  s    
zDateMixin.get_date_fieldc             C   s   | j S )zj
        Returns `True` if the view should be allowed to display objects from
        the future.
        )allow_future)r   r   r   r   get_allow_future  s    zDateMixin.get_allow_futurec             C   s6   | j dkr| j j n| j }|jj| j }t|tjS )zq
        Return `True` if the date field is a `DateTimeField` and `False`
        if it's a `DateField`.
        N)modelget_queryset_meta	get_fieldrR   
isinstancer   ZDateTimeField)r   rU   fieldr   r   r   uses_datetime_field   s    zDateMixin.uses_datetime_fieldc             C   s2   | j r.tjj|tjj}tjr.tj|tj	 }|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.
        )
r[   r>   combinetimeminr   USE_TZr   Z
make_awareZget_current_timezone)r   valuer   r   r   _make_date_lookup_arg*  s
    zDateMixin._make_date_lookup_argc             C   sN   | j  }| jrB| j|}| j|tjdd }d| |d| |iS ||iS dS )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$   )r=   z%s__gtez%s__ltN)rR   r[   ra   r>   r?   )r   r!   rP   sinceuntilr   r   r   _make_single_date_lookup7  s    
z"DateMixin._make_single_date_lookup)r*   r+   r,   r-   rP   rS   rR   rT   r
   r[   ra   rd   r   r   r   r   rO     s   

rO   c               @   sJ   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
dddZdS )BaseDateListViewzP
    Abstract base class for date-based views displaying a list of objects.
    Fr   c             O   s8   | j  \| _| _}| j| j| jd}|j| | j|S )N)object_list	date_list)get_dated_itemsrg   rf   Zget_context_dataupdateZrender_to_response)r   r   argsr   Zextra_contextcontextr   r   r   getR  s
    

zBaseDateListView.getc             C   s   t ddS )z5
        Obtain the list of dates and items.
        z>A DateView must provide an implementation of get_dated_items()N)NotImplementedError)r   r   r   r   rh   Y  s    z BaseDateListView.get_dated_itemsc             C   s   | j dkrd| j  S | j S )zw
        Returns the field or fields to use for ordering the queryset; uses the
        date field by default.
        Nz-%s)orderingrR   )r   r   r   r   get_ordering_  s    zBaseDateListView.get_orderingc       	      K   s   | j  jf |}| j }| j }| j }| j|}|s^| jrDtj nt	 }|jf d| |i}|s|dkrvt
|dkn|j  }|rttddt|jjji |S )zs
        Get a queryset properly filtered according to `allow_future` and any
        extra lookup kwargs.
        z%s__lteNr   z$No %(verbose_name_plural)s availableverbose_name_plural)rV   filterrR   rT   get_allow_emptyZget_paginate_byr[   r   nowtimezone_todaylenexistsr   r   r	   rU   rW   rp   )	r   lookupqsrP   rS   allow_emptyZpaginate_byrs   Zis_emptyr   r   r   get_dated_querysetf  s    
z#BaseDateListView.get_dated_querysetc             C   s   | j S )z^
        Get the aggregation period for the list of dates: 'year', 'month', or 'day'.
        )date_list_period)r   r   r   r   get_date_list_period  s    z%BaseDateListView.get_date_list_periodNASCc             C   s~   | j  }| j }|dkr | j }| jr6|j|||}n|j|||}|dk	rz| rz| rzt|jjj	}t
tdd|i |S )z
        Get a date list by calling `queryset.dates/datetimes()`, checking
        along the way for empty lists that aren't allowed.
        Nz$No %(verbose_name_plural)s availablerp   )rR   rr   r|   r[   Z	datetimesdatesr	   rU   rW   rp   r   r   )r   querysetZ	date_typern   rP   ry   rg   namer   r   r   get_date_list  s    zBaseDateListView.get_date_list)Nr}   )r*   r+   r,   r-   ry   r{   rl   rh   ro   rz   r|   r   r   r   r   r   re   K  s   re   c               @   s   e Zd ZdZdZdd ZdS )BaseArchiveIndexViewzV
    Base class for archives of date-based items.

    Requires a response mixin.
    latestc             C   s,   | j  }| j|dd}|s"|j }||i fS )zL
        Return (date_list, items, extra_context) for this request.
        ZDESC)rn   )rz   r   none)r   rx   rg   r   r   r   rh     s
    z$BaseArchiveIndexView.get_dated_itemsN)r*   r+   r,   r-   Zcontext_object_namerh   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZdS )ArchiveIndexViewz0
    Top-level archive of date-based items.
    Z_archiveN)r*   r+   r,   r-   template_name_suffixr   r   r   r   r     s   r   c               @   s(   e Zd ZdZdZdZdd Zdd ZdS )	BaseYearArchiveViewz4
    List of objects published in a given year.
    r%   Fc       	      C   s   | j  }| j }t|| j }| j|}| j| j|}d| |d| |i}| jf |}| j|}| j sr|j	 }|||| j
|| j|dfS )zL
        Return (date_list, items, extra_context) for this request.
        z%s__gtez%s__lt)r   Z	next_yearZprevious_year)r   rR   _date_from_stringr   ra   r(   rz   r   get_make_object_listr   r"   r#   )	r   r   rP   r!   rb   rc   lookup_kwargsrx   rg   r   r   r   rh     s    

z#BaseYearArchiveView.get_dated_itemsc             C   s   | j S )zo
        Return `True` if this view should contain the full list of objects in
        the given year.
        )make_object_list)r   r   r   r   r     s    z(BaseYearArchiveView.get_make_object_listN)r*   r+   r,   r-   r{   r   rh   r   r   r   r   r   r     s
   r   c               @   s   e Zd ZdZdZdS )YearArchiveViewz4
    List of objects published in a given year.
    Z_archive_yearN)r*   r+   r,   r-   r   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZdd ZdS )BaseMonthArchiveViewz5
    List of objects published in a given month.
    r&   c       
      C   s   | j  }| j }| j }t|| j || j }| j|}| j| j|}d| |d| |i}| jf |}| j	|}	|	||| j
|| j|dfS )zL
        Return (date_list, items, extra_context) for this request.
        z%s__gtez%s__lt)r%   
next_monthprevious_month)r   r1   rR   r   r   r0   ra   r5   rz   r   r2   r3   )
r   r   r%   rP   r!   rb   rc   r   rx   rg   r   r   r   rh     s    


z$BaseMonthArchiveView.get_dated_itemsN)r*   r+   r,   r-   r{   rh   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZdS )MonthArchiveViewz5
    List of objects published in a given month.
    Z_archive_monthN)r*   r+   r,   r-   r   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdd ZdS )BaseWeekArchiveViewz4
    List of objects published in a given week.
    c             C   s   | j  }| j }| j }| j }ddd| }t|| j |d||}| j|}| j| j|}d| |d| |i}	| jf |	}
d|
|| j	|| j
|dfS )	zL
        Return (date_list, items, extra_context) for this request.
        10)z%Wz%Uz%wz%s__gtez%s__ltN)rE   Z	next_weekZprevious_week)r   rF   rR   rD   r   r   ra   rK   rz   rG   rH   )r   r   rE   rP   rC   Z
week_startr!   rb   rc   r   rx   r   r   r   rh     s&    

z#BaseWeekArchiveView.get_dated_itemsN)r*   r+   r,   r-   rh   r   r   r   r   r     s   r   c               @   s   e Zd ZdZdZdS )WeekArchiveViewz4
    List of objects published in a given week.
    Z_archive_weekN)r*   r+   r,   r-   r   r   r   r   r   r   ;  s   r   c               @   s    e Zd ZdZdd Zdd ZdS )BaseDayArchiveViewz3
    List of objects published on a given day.
    c             C   s@   | j  }| j }| j }t|| j || j || j }| j|S )zL
        Return (date_list, items, extra_context) for this request.
        )r   r1   r:   r   r   r0   r9   _get_dated_items)r   r   r%   r&   r!   r   r   r   rh   F  s    
z"BaseDayArchiveView.get_dated_itemsc             C   sD   | j |}| jf |}d||| j|| j|| j|| j|dfS )z
        Do the actual heavy lifting of getting the dated items; this accepts a
        date object so that TodayArchiveView can be trivial.
        N)r&   Zprevious_dayZnext_dayr   r   )rd   rz   r<   r;   r3   r2   )r   r!   r   rx   r   r   r   r   T  s    
z#BaseDayArchiveView._get_dated_itemsN)r*   r+   r,   r-   rh   r   r   r   r   r   r   B  s   r   c               @   s   e Zd ZdZdZdS )DayArchiveViewz3
    List of objects published on a given day.
    _archive_dayN)r*   r+   r,   r-   r   r   r   r   r   r   e  s   r   c               @   s   e Zd ZdZdd ZdS )BaseTodayArchiveViewz*
    List of objects published today.
    c             C   s   | j tjj S )zL
        Return (date_list, items, extra_context) for this request.
        )r   r>   r!   today)r   r   r   r   rh   q  s    z$BaseTodayArchiveView.get_dated_itemsN)r*   r+   r,   r-   rh   r   r   r   r   r   l  s   r   c               @   s   e Zd ZdZdZdS )TodayArchiveViewz*
    List of objects published today.
    r   N)r*   r+   r,   r-   r   r   r   r   r   r   x  s   r   c                   s"   e Zd ZdZd fdd	Z  ZS )BaseDateDetailViewz
    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.
    Nc                s   | j  }| j }| j }t|| j || j || j }|dkrF| j n|}| j  r|t	j
j krttd|jjj| jjd | j|}|jf |}tt| j|dS )z7
        Get the object this request displays.
        NzZFuture %(verbose_name_plural)s not available because %(class_name)s.allow_future is False.)rp   
class_name)r   )r   r1   r:   r   r   r0   r9   rV   rT   r>   r!   r   r   r   rU   rW   rp   rQ   r*   rd   rq   superr   
get_object)r   r   r   r%   r&   r!   rx   r   )rQ   r   r   r     s    

zBaseDateDetailView.get_object)N)r*   r+   r,   r-   r   __classcell__r   r   )rQ   r   r     s   r   c               @   s   e Zd ZdZdZdS )DateDetailViewz
    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.
    Z_detailN)r*   r+   r,   r-   r   r   r   r   r   r     s   r    __c       	      C   sf   |j |||f}|j | ||f}ytjjt||j S  tk
r`   ttd||d Y nX dS )z
    Helper: 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.
    z;Invalid date string '%(datestr)s' given format '%(format)s')datestrformatN)joinr>   strptimer   r!   rN   r   r   )	r   r   r%   r/   r&   r8   delimr   r   r   r   r   r     s    r   c             C   sJ  | j  }| j }| j }t| d| }t| d| }|||| }	}
|r|rd||	tjdd }n|
}|sv|t krz|S dS n|rd| | j|	i}d| }nd| | j|
i}|}|s| jrt	j
 }nt }||d	| < | j jf |j|}yt|d
 |}W n tk
r   dS X | jr>tjr6t	j|}|j }||S dS )a^  
    Helper: 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$   )r=   Nz%s__ltz-%sz%s__gtez%s__lter   )rR   rr   rT   getattrr>   r?   rt   ra   r[   r   rs   rV   rq   Zorder_by
IndexErrorr   r_   	localtimer!   )Zgeneric_viewr!   r   r   rP   ry   rS   Zget_currentZget_nextstartendresultrw   rn   rs   rx   r   r   r   r      sB    


r    c               C   s&   t jrtjtj j S tjj S dS )z;
    Return the current date in the current time zone.
    N)r   r_   r   r   rs   r!   r>   r   r   r   r   r   rt     s    rt   )r   r   r   r   r   )5
__future__r   r>   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.httpr   Zdjango.utilsr   Zdjango.utils.encodingr   r	   Zdjango.utils.functionalr
   Zdjango.utils.translationr   r   Zdjango.views.generic.baser   Zdjango.views.generic.detailr   r   Zdjango.views.generic.listr   r   objectr   r.   r7   rB   rO   re   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    rt   r   r   r   r   <module>   sF   8;8FDQ-"&#%
Z