
v^Wc                 @   s  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 d  d l m Z d  d	 l m Z d  d
 l m Z m Z d  d l m Z m Z Gd d   d  Z Gd d   d  Z Gd d   d  Z Gd d   d  Z Gd d   d  Z Gd d   d e e e  Z Gd d   d e  Z Gd d   d e e  Z Gd d   d e e  Z  Gd d   d e e   Z! Gd  d!   d! e e e  Z" Gd" d#   d# e e"  Z# Gd$ d%   d% e e e  Z$ Gd& d'   d' e e$  Z% Gd( d)   d) e e e e  Z& Gd* d+   d+ e e&  Z' Gd, d-   d- e&  Z( Gd. d/   d/ e e(  Z) Gd0 d1   d1 e e e e e  Z* Gd2 d3   d3 e e*  Z+ d4 d4 d4 d4 d5 d6 d7  Z, d8 d9   Z- d: d;   Z. d S)<    N)settings)ImproperlyConfigured)models)Http404)timezone)cached_property)gettext)View)BaseDetailView!SingleObjectTemplateResponseMixin)MultipleObjectMixin#MultipleObjectTemplateResponseMixinc               @   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   Z d S)	YearMixinz-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-build-8lau8j11/django/django/views/generic/dates.pyget_year_format   s    zYearMixin.get_year_formatc             C   sz   |  j  } | d k rv y |  j d } WnM t k
 ru y |  j j d } Wn$ t k
 rp t t d    Yn XYn X| S)z8Return 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 d S)zGet the next valid year.is_previousFperiodr   )_get_next_prev)r   dater   r   r   get_next_year,   s    zYearMixin.get_next_yearc             C   s   t  |  | d d d d S)zGet the previous valid year.r   Tr   r   )r   )r   r   r   r   r   get_previous_year0   s    zYearMixin.get_previous_yearc             C   sR   y' | j  d | j d d d d d  SWn$ t k
 rM t t d    Yn Xd S)z
        Return the start date of the next interval.

        The interval is defined by start date <= item date < next start date.
        r      monthdayzDate out of rangeN)replacer   
ValueErrorr   r   )r   r   r   r   r   _get_next_year4   s    'zYearMixin._get_next_yearc             C   s   | j  d d d d  S)z.Return the start date of the current interval.r"   r!   r#   )r$   )r   r   r   r   r   _get_current_year?   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               @   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   Z d S)
MonthMixinz.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_formatI   s    zMonthMixin.get_month_formatc             C   sz   |  j  } | d k rv y |  j d } WnM t k
 ru y |  j j d } Wn$ t k
 rp t t d    Yn XYn X| S)z9Return 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_monthP   s    	zMonthMixin.get_monthc             C   s   t  |  | d d d d S)zGet the next valid month.r   Fr   r"   )r   )r   r   r   r   r   get_next_month]   s    zMonthMixin.get_next_monthc             C   s   t  |  | d d d d S)zGet the previous valid month.r   Tr   r"   )r   )r   r   r   r   r   get_previous_montha   s    zMonthMixin.get_previous_monthc             C   s   | j  d k r` y' | j d | j d d d d d  SWq} t k
 r\ t t d    Yq} Xn | j d | j  d d d  Sd 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#   zDate out of rangeN)r"   r$   r   r%   r   r   )r   r   r   r   r   _get_next_monthe   s    'zMonthMixin._get_next_monthc             C   s   | j  d d  S)z/Return the start date of the previous interval.r#   r!   )r$   )r   r   r   r   r   _get_current_months   s    zMonthMixin._get_current_month)r(   r)   r*   r+   r-   r"   r.   r/   r0   r1   r3   r4   r   r   r   r   r,   D   s   r,   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   Z d S)DayMixinz,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   sz   |  j  } | d k rv y |  j d } WnM t k
 ru y |  j j d } Wn$ t k
 rp t t d    Yn XYn X| S)z7Return 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 d S)zGet the next valid day.r   Fr   r#   )r   )r   r   r   r   r   get_next_day   s    zDayMixin.get_next_dayc             C   s   t  |  | d d d d S)zGet the previous valid day.r   Tr   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.
        daysr!   )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+   r6   r#   r7   r8   r9   r:   r>   r?   r   r   r   r   r5   x   s   r5   c               @   sv   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)	WeekMixinz-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   sz   |  j  } | d k rv y |  j d } WnM t k
 ru y |  j j d } Wn$ t k
 rp t t d    Yn XYn X| S)z8Return the week for which this view should display data.NweekzNo week specified)rC   r   r   r   r   r   r   )r   rC   r   r   r   get_week   s    	zWeekMixin.get_weekc             C   s   t  |  | d d d d S)zGet the next valid week.r   Fr   rC   )r   )r   r   r   r   r   get_next_week   s    zWeekMixin.get_next_weekc             C   s   t  |  | d d d d S)zGet the previous valid week.r   Tr   rC   )r   )r   r   r   r   r   get_previous_week   s    zWeekMixin.get_previous_weekc             C   sP   y% | t  j d d |  j |   SWn$ t k
 rK t t d    Yn Xd S)z
        Return the start date of the next interval.

        The interval is defined by start date <= item date < next start date.
        r;      zDate out of rangeN)r<   r=   _get_weekdayOverflowErrorr   r   )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=   rH   )r   r   r   r   r   _get_current_week   s    zWeekMixin._get_current_weekc             C   sT   |  j    } | d k r" | j   S| d k r@ | j   d d St 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!   rG   zunknown week format: %sN)rB   weekdayr%   )r   r   rA   r   r   r   rH      s    
zWeekMixin._get_weekday)r(   r)   r*   r+   rA   rC   rB   rD   rE   rF   rJ   rK   rH   r   r   r   r   r@      s   r@   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)	DateMixinz3Mixin class for views manipulating date-based data.NFc             C   s,   |  j  d k r% t d |  j j   |  j  S)z7Get 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)zi
        Return `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   sO   |  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_fieldrP   
isinstancer   ZDateTimeField)r   rS   fieldr   r   r   uses_datetime_field   s    'zDateMixin.uses_datetime_fieldc             C   s@   |  j  r< t j j | t j j  } t j r< 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.
        )	rY   r<   combinetimeminr   USE_TZr   Z
make_aware)r   valuer   r   r   _make_date_lookup_arg  s
    		zDateMixin._make_date_lookup_argc             C   si   |  j    } |  j r[ |  j |  } |  j | t j d d   } d | | d | | i S| | i Sd 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)rP   rY   r_   r<   r=   )r   r   rN   sinceuntilr   r   r   _make_single_date_lookup  s    	
z"DateMixin._make_single_date_lookup)r(   r)   r*   r+   rN   rQ   rP   rR   r   rY   r_   rb   r   r   r   r   rM      s   

rM   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 d d  Z d S)BaseDateListViewzFAbstract base class for date-based views displaying a list of objects.Fr   c             O   sI   |  j    \ |  _ |  _ } |  j d |  j d |  j |  } |  j |  S)Nobject_list	date_list)get_dated_itemsre   rd   Zget_context_dataZrender_to_response)r   r   argsr   Zextra_contextcontextr   r   r   get*  s    			zBaseDateListView.getc             C   s   t  d   d S)z#Obtain the list of dates and items.z>A DateView must provide an implementation of get_dated_items()N)NotImplementedError)r   r   r   r   rf   3  s    z BaseDateListView.get_dated_itemsc             C   s$   |  j  d k r d |  j   S|  j  S)zu
        Return the field or fields to use for ordering the queryset; use the
        date field by default.
        Nz-%s)orderingrP   )r   r   r   r   get_ordering7  s    zBaseDateListView.get_orderingc       	      K   s   |  j    j |   } |  j   } |  j   } |  j   } |  j |  } | s |  j rc t j   n t	   } | j d | | i   } | s | d k r | n
 | j
   } | r t t d  d | j j j i   | S)zs
        Get a queryset properly filtered according to `allow_future` and any
        extra lookup kwargs.
        z%s__lteNz$No %(verbose_name_plural)s availableverbose_name_plural)rT   filterrP   rR   get_allow_emptyZget_paginate_byrY   r   nowtimezone_todayexistsr   r   rS   rU   rm   )	r   lookupqsrN   rQ   allow_emptyZpaginate_byrp   Zis_emptyr   r   r   get_dated_queryset>  s     z#BaseDateListView.get_dated_querysetc             C   s   |  j  S)zf
        Get the aggregation period for the list of dates: 'year', 'month', or
        'day'.
        )date_list_period)r   r   r   r   get_date_list_periodX  s    z%BaseDateListView.get_date_list_periodNZASCc             C   s   |  j    } |  j   } | d k r0 |  j   } |  j rQ | j | | |  } n | j | | |  } | d k	 r | r | r t t d  d | j j	 j
 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 availablerm   )rP   ro   rx   rY   Z	datetimesdatesr   r   rS   rU   rm   )r   querysetZ	date_typerk   rN   ru   re   r   r   r   get_date_list_  s    		zBaseDateListView.get_date_list)r(   r)   r*   r+   ru   rw   ri   rf   rl   rv   rx   r{   r   r   r   r   rc   %  s   	rc   c               @   s(   e  Z d  Z d Z d Z d d   Z d S)BaseArchiveIndexViewzQ
    Base class for archives of date-based items. Requires a response mixin.
    latestc             C   s@   |  j    } |  j | d d } | s3 | j   } | | i  f S)z:Return (date_list, items, extra_context) for this request.rk   ZDESC)rv   r{   none)r   rt   re   r   r   r   rf   }  s
    z$BaseArchiveIndexView.get_dated_itemsN)r(   r)   r*   r+   Zcontext_object_namerf   r   r   r   r   r|   w  s   r|   c               @   s   e  Z d  Z d Z d Z d S)ArchiveIndexViewz&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)	BaseYearArchiveViewz*List of objects published in a given year.r"   Fc       	   	   C   s   |  j    } |  j   } t | |  j    } |  j |  } |  j |  j |   } d | | d | | i } |  j |   } |  j |  } |  j   s | j	   } | | d | d |  j
 |  d |  j |  i f S)z:Return (date_list, items, extra_context) for this request.z%s__gtez%s__ltr   Z	next_yearZprevious_year)r   rP   _date_from_stringr   r_   r&   rv   r{   get_make_object_listr~   r   r    )	r   r   rN   r   r`   ra   lookup_kwargsrt   re   r   r   r   rf     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+   rw   r   rf   r   r   r   r   r   r     s
   r   c               @   s   e  Z d  Z d Z d Z d S)YearArchiveViewz*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)BaseMonthArchiveViewz+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 |   } |  j	 |  }	 |	 | d | d |  j
 |  d |  j |  i f S)z:Return (date_list, items, extra_context) for this request.z%s__gtez%s__ltr"   
next_monthprevious_month)r   r/   rP   r   r   r.   r_   r3   rv   r{   r0   r1   )
r   r   r"   rN   r   r`   ra   r   rt   re   r   r   r   rf     s    
z$BaseMonthArchiveView.get_dated_itemsN)r(   r)   r*   r+   rw   rf   r   r   r   r   r     s   r   c               @   s   e  Z d  Z d Z d Z d S)MonthArchiveViewz+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)BaseWeekArchiveViewz*List of objects published in a given week.c             C   s,  |  j    } |  j   } |  j   } |  j   } d d d d i } y | | } Wn7 t k
 r t d | d j t |   f   Yn Xt | |  j	   | d | |  } |  j
 |  } |  j
 |  j |   }	 d | | d	 | |	 i }
 |  j |
   } d
 | d | d |  j |  d |  j |  i f S)z:Return (date_list, items, extra_context) for this request.z%W1z%U0z'Unknown week format %r. Choices are: %sz, z%wz%s__gtez%s__ltNrC   Z	next_weekZprevious_week)r   rD   rP   rB   r   r%   joinsortedr   r   r_   rJ   rv   rE   rF   )r   r   rC   rN   rA   Zweek_choicesZ
week_startr   r`   ra   r   rt   r   r   r   rf     s.    !
z#BaseWeekArchiveView.get_dated_itemsN)r(   r)   r*   r+   rf   r   r   r   r   r     s   r   c               @   s   e  Z d  Z d Z d Z d S)WeekArchiveViewz*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)BaseDayArchiveViewz)List of objects published on a given day.c             C   s^   |  j    } |  j   } |  j   } t | |  j   | |  j   | |  j    } |  j |  S)z:Return (date_list, items, extra_context) for this request.)r   r/   r8   r   r   r.   r7   _get_dated_items)r   r   r"   r#   r   r   r   r   rf     s    z"BaseDayArchiveView.get_dated_itemsc             C   sm   |  j  |  } |  j |   } d | d | d |  j |  d |  j |  d |  j |  d |  j |  i f S)z
        Do the actual heavy lifting of getting the dated items; this accepts a
        date object so that TodayArchiveView can be trivial.
        Nr#   Zprevious_dayZnext_dayr   r   )rb   rv   r:   r9   r1   r0   )r   r   r   rt   r   r   r   r     s    z#BaseDayArchiveView._get_dated_itemsN)r(   r)   r*   r+   rf   r   r   r   r   r   r   	  s   r   c               @   s   e  Z d  Z d Z d Z d S)DayArchiveViewz)List of objects published on a given day._archive_dayN)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)BaseTodayArchiveViewz List of objects published today.c             C   s   |  j  t j j    S)z:Return (date_list, items, extra_context) for this request.)r   r<   r   today)r   r   r   r   rf   0  s    z$BaseTodayArchiveView.get_dated_itemsN)r(   r)   r*   r+   rf   r   r   r   r   r   -  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   5  s   r   c                   s+   e  Z d  Z d Z d   f d d  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 ri |  j   n | } |  j   r | t	 j
 j   k r t t d  d | j j j d |  j j i   |  j |  } | j |   } t   j d |  S)z%Get the object this request displays.NzZFuture %(verbose_name_plural)s not available because %(class_name)s.allow_future is False.rm   
class_namerz   )r   r/   r8   r   r   r.   r7   rT   rR   r<   r   r   r   r   rS   rU   rm   rO   r(   rb   rn   super
get_object)r   rz   r   r"   r#   r   rt   r   )rO   r   r   r   ?  s    "zBaseDateDetailView.get_object)r(   r)   r*   r+   r   r   r   )rO   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   s   | | | | | } t  |   | t  |  | t  |  } y t j j | |  j   SWn4 t k
 r t t d  d | d | i   Yn Xd S)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.
    uC   Invalid date string “%(datestr)s” given format “%(format)s”datestrformatN)strr<   strptimer   r%   r   r   )	r   r   r"   r-   r#   r6   delimr   r   r   r   r   r   e  s    (r   c             C   s  |  j    } |  j   } |  j   } t |  d |  } t |  d |  } | |  | |  }	 }
 | r | r | |	 t j d d   } n |
 } | s | t   k r | Sd Sn| r d | |  j |	  i } d | } n d | |  j |
  i } | } | s4|  j rt	 j
   } n	 t   } | | d	 | <|  j   j |   j |  } y t | d
 |  } Wn t k
 rd SYn X|  j rt j rt	 j |  } | j   } | |  Sd 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;   r!   Nz%s__ltz-%sz%s__gtez%s__lter   )rP   ro   rR   getattrr<   r=   rq   r_   rY   r   rp   rT   rn   Zorder_by
IndexErrorr   r]   	localtimer   )Zgeneric_viewr   r   r   rN   ru   rQ   Zget_currentZget_nextstartendresultrs   rk   rp   rt   r   r   r   r   u  sB    					r   c               C   s$   t  j r t j   St j j   Sd S)z1Return the current date in the current time zone.N)r   r]   r   Z	localdater<   r   r   r   r   r   r   rq     s    	
rq   )/r<   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.httpr   Zdjango.utilsr   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   r   r,   r5   r@   rM   rc   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rq   r   r   r   r   <module>   sB   14.?@R)&"#Z