
^Q\b                 @   s  d  d l  m Z d  d l 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 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 m Z m Z m Z Gd d   d e   Z! Gd d   d e"  Z# Gd d   d e"  Z$ e j% e!  Gd d   d e$   Z& e& d d d d d  Z' d S)    )unicode_literalsN)OrderedDict)count)settings)	Paginator)get_template)six)
force_text   )columns)RequestConfig)	TableData)	BoundRows)AccessorAttributeDictOrderByOrderByTupleSequencec                   s(   e  Z d  Z d Z   f d d   Z   S)DeclarativeColumnsMetaclassz
    Metaclass that converts `.Column` objects defined on a class to the
    dictionary `.Table.base_columns`, taking into account parent class
    `base_columns` as well.
    c                s  t  | j d d    | d <} g  i  } } xU | j   D]G \ } } t | t j  rw d | _ | j | | f  q: | | | <q: W| } | j d d d    g  }	 x? t	 |  D]1 }
 t
 |
 d  r t |
 j j    |	 }	 q q Wt |	  } | j rt   } | j d  k	 r[xu | j D]4 } t |  j | j  } t j j |  | | <q Wn3 x0 | j j j D] } t j j |  | | j <qkWxL | j   D]; \ } } | | k r| | j d k rqn  | | | <qWn  | j t |   x- | j D]" } | | k r| j |  qqWx* | D]" } | | k r'| j |  q'q'Wxf | j   D]X } d  } | | j k r~d } n  | | j k rd } n  | d  k	 rZ| | | _ qZqZW| | d <t t |   j |  | | |  S)	NMeta_metaTkeyc             S   s   |  d j  S)Nr
   )Zcreation_counter)x r   J/var/www/dbchiro/venv/lib/python3.4/site-packages/django_tables2/tables.py<lambda>)   s    z5DeclarativeColumnsMetaclass.__new__.<locals>.<lambda>base_columnsF)TableOptionsgetitems
isinstancer   ZColumnZ	_explicitappendsortreversedhasattrlistr   r   modelfieldsr   	get_fieldZlibraryZcolumn_for_fieldr   nameupdateexcludepopkeyslocalize
unlocalizesuperr   __new__)Zmcsr)   basesattrsoptscols	remainder	attr_nameattrZparent_columnsbaser   extra
field_namefieldr   colZ	exclusionZcol_nameZlocalize_column)	__class__r   r   r1      sV     	 				
z#DeclarativeColumnsMetaclass.__new__)__name__
__module____qualname____doc__r1   r   r   )r>   r   r      s   r   c                   s+   e  Z d  Z d Z d   f d d  Z   S)r   a  
    Extracts and exposes options for a `.Table` from a `.Table.Meta`
    when the table is defined. See `.Table` for documentation on the impact of
    variables in this class.

    Arguments:
        options (`.Table.Meta`): options for a table from `.Table.Meta`
    Nc                s^  t  t |   j   t t d d  } t t d i   } t t | d |   |  _ t | d i   |  _ t | d i   |  _ t | d d  |  _	 t | d	 d   |  _
 t | d
 d   |  _ t | d f   |  _ t | d d   } t | t j  r | f } n  | d  k	 rt |  n d  |  _ t | d d  |  _ t | d d  |  _ t | d d  |  _ t | d d  |  _ t | d d  |  _ t | d d  |  _ t t | d f    |  _ t | d d  |  _ t | d d   |  _ t | d  rt | d |  |  _ t j d t   n t | d |  |  _ t | d f   |  _! t | d f   |  _" d  S) NDJANGO_TABLES2_TEMPLATEzdjango_tables2/table.htmlDJANGO_TABLES2_TABLE_ATTRSr3   	row_attrspinned_row_attrsdefaultu   —
empty_textr'   r+   order_byorder_by_fieldr"   
page_fieldpageper_page   per_page_fieldprefix show_headerTsequence	orderabler&   templatez=Table.Meta.template is deprecated. Use template_name instead.template_namer.   r/   )#r0   r   __init__getattrr   r   r3   rE   rF   rG   rH   r'   r+   r    r   string_typesr   rI   rJ   rK   rM   rO   rP   rR   r   rS   rT   r&   r$   rV   warningswarnDeprecationWarningr.   r/   )selfoptionsrC   rD   rI   )r>   r   r   rW   q   s:    !zTableOptions.__init__)r?   r@   rA   rB   rW   r   r   )r>   r   r   h   s   r   c                   se  e  Z d  Z d Z d d d d d d d d d d d d d d d d d d d d   f d d  Z d d   Z d d	   Z d
 d   Z d d   Z d d d  Z	 d d   Z
 e d d    Z e j d d    Z e d d    Z e j d d    Z e d d    Z e j d d    Z e d d    Z e j d d    Z e d d d d   Z e d! d"    Z e j d# d"    Z e d$ d%    Z e j d& d%    Z e d' d(    Z e d) d*    Z e d+ d,    Z e d- d.    Z e j d/ d.    Z e d0 d1    Z e j d2 d1    Z e d3 d4    Z e j d5 d4    Z d6 d7   Z   S)8	TableBasea  
    A representation of a table.

    Arguments:
        data (queryset, list of dicts): The data to display.
            This is a required variable, a `TypeError` will be raised if it's not passed.

        order_by: (tuple or str): The default ordering tuple or comma separated str.
            A hyphen `-` can be used to prefix a column name to indicate
            *descending* order, for example: `('name', '-age')` or `name,-age`.

        orderable (bool): Enable/disable column ordering on this table

        empty_text (str): Empty text to render when the table has no data.
            (default `.Table.Meta.empty_text`)

        exclude (iterable or str): The names of columns that shouldn't be
            included in the table.

        attrs (dict): HTML attributes to add to the ``<table>`` tag.
            When accessing the attribute, the value is always returned as an
            `.AttributeDict` to allow easily conversion to HTML.

        row_attrs: Add custom html attributes to the table rows.
            Allows custom HTML attributes to be specified which will be added
            to the ``<tr>`` tag of the rendered table.

        pinned_row_attrs: Same as row_attrs but for pinned rows.

        sequence (iterable): The sequence/order of columns the columns (from
            left to right).

            Items in the sequence must be :term:`column names <column name>`, or
            `'...'` (string containing three periods). `'...'` can be used as a
            catch-all for columns that aren't specified.

        prefix (str): A prefix for querystring fields.
            To avoid name-clashes when  using multiple tables on single page.

        order_by_field (str): If not `None`, defines the name of the *order by*
            querystring field in the url.

        page_field (str): If not `None`, defines the name of the *current page*
            querystring field.

        per_page_field (str): If not `None`, defines the name of the *per page*
            querystring field.

        template_name (str): The template to render when using ``{% render_table %}``
            (defaults to DJANGO_TABLES2_TEMPLATE, which is ``'django_tables2/table.html'``
            by default).

        default (str): Text to render in empty cells (determined by
            `.Column.empty_values`, default `.Table.Meta.default`)

        request: Django's request to avoid using `RequestConfig`

        show_header (bool): If `False`, the table will not have a header
            (`<thead>`), defaults to `True`

        show_footer (bool): If `False`, the table footer will not be rendered,
            even if some columns have a footer, defaults to `True`.

        extra_columns (str, `.Column`): list of `(name, column)`-tuples containing
            extra columns to add to the instance.
    NTc                sw  t  t |   j   | d  k r@ t d j t |   j    n  | pO |  j j |  _ |	 |  _	 t
 j d | d |   |  _ | d  k r |  j j } n  | |  _ t | p |  j j  |  _ i |  j   d 6|  j   d 6|  _ t d |  j d |  d |  j  |  _ t | d  k	 r| n	 |  j j  |  _ t | p8|  j j  |  _ | d  k	 rS| n	 |  j j |  _ | |  _ |
 |  _ | |  _ | |  _ | |  _ | |  _ | |  _ t j  t |   j!    | d  k	 rx! | D] \ } } |   | <qWn  |	 d  k	 rt" |	  }	 nX |  j j	 r|  j j	 }	 n= |  j j# d  k	 rPt" t$ |  j j#  d  }	 n t" d  }	 |	 j%   j&    |  _' t(   f d d	   |	 D    t) j* |     |  _) | d  k r|  j j+ d  k	 r|  j j+ } n  | d  k rd  |  _, |  j j- } | d  k	 r| |  _+ qn	 | |  _+ | d  k	 rB| |  _. t/ j0 d
 t1  n	 | |  _. | rgt2 |  j3 |   n  t4   |  _5 d  S)NzArgument data to {} is requireddatatabletopZbottompinned_data...c             3   s+   |  ]! } |   k r |   | f Vq d  S)Nr   ).0r   )r   r   r   	<genexpr>  s    z%TableBase.__init__.<locals>.<genexpr>zDtemplate argument to Table is deprecated. Use template_name instead.)rd   )rd   )6r0   r_   rW   	TypeErrorformattyper?   r   r+   rS   r   Z	from_datar`   rG   r   rF   get_top_pinned_dataget_bottom_pinned_datarc   r   rowsr3   rE   rH   rT   rP   rJ   rK   rO   rR   show_footercopydeepcopyr   r   r'   tupleexpandr-   	_sequencer   r   ZBoundColumnsrI   	_order_byZorderingrV   rZ   r[   r\   r   Z	configurer   _counter)r]   r`   rI   rT   rH   r+   r3   rE   rF   rS   rP   rJ   rK   rO   rU   rV   rG   requestrR   rm   Zextra_columnsr)   column)r>   )r   r   rW      sl    !		$'!											zTableBase.__init__c             C   s   d S)a%  
        Return data for top pinned rows containing data for each row.
        Iterable type like: queryset, list of dicts, list of objects.
        Having a non-zero number of pinned rows
        will not result in an empty resultset message being rendered,
        even if there are no regular data rows

        Returns:
            `None` (default) no pinned rows at the top, iterable, data for pinned rows at the top.

        Note:
            To show pinned row this method should be overridden.

        Example:
            >>> class TableWithTopPinnedRows(Table):
            ...     def get_top_pinned_data(self):
            ...         return [{
            ...             'column_a' : 'some value',
            ...             'column_c' : 'other value',
            ...         }]
        Nr   )r]   r   r   r   rj   6  s    zTableBase.get_top_pinned_datac             C   s   d S)a4  
        Return data for bottom pinned rows containing data for each row.
        Iterable type like: queryset, list of dicts, list of objects.
        Having a non-zero number of pinned rows
        will not result in an empty resultset message being rendered,
        even if there are no regular data rows

        Returns:
            `None` (default) no pinned rows at the bottom, iterable, data for pinned rows at the bottom.

        Note:
            To show pinned row this method should be overridden.

        Example:
            >>> class TableWithBottomPinnedRows(Table):
            ...     def get_bottom_pinned_data(self):
            ...         return [{
            ...             'column_a' : 'some value',
            ...             'column_c' : 'other value',
            ...         }]
        Nr   )r]   r   r   r   rk   N  s    z TableBase.get_bottom_pinned_datac             C   s   d S)a  
        A way to hook into the moment just before rendering the template.

        Can be used to hide a column.

        Arguments:
            request: contains the `WGSIRequest` instance, containing a `user` attribute if
                `.django.contrib.auth.middleware.AuthenticationMiddleware` is added to
                your `MIDDLEWARE_CLASSES`.

        Example::

            class Table(tables.Table):
                name = tables.Column(orderable=False)
                country = tables.Column(orderable=False)

                def before_render(self, request):
                    if request.user.has_perm('foo.delete_bar'):
                        self.columns.hide('country')
                    else:
                        self.columns.show('country')
        Nr   )r]   ru   r   r   r   before_renderf  s    zTableBase.before_renderc             C   sI   t    |  _ t |  j  } i |  d 6| d 6} |  j |  | j |  S)zU
        Render the table to an HTML table, adding `request` to the context.
        ra   ru   )r   rt   r   rV   rw   Zrender)r]   ru   rU   contextr   r   r   as_html  s    
zTableBase.as_htmlc             #   s{     d k r f    n    f d d     f d d   |  j  D Vx2 |  j D]'    f d d    j j  D VqL Wd S)a  
        Return a row iterator of the data which would be shown in the table where
        the first row is the table headers.

        arguments:
            exclude_columns (iterable): columns to exclude in the data iterator.

        This can be used to output the table data as CSV, excel, for example using the
        `~.export.ExportMixin`.

        If a column is defined using a :ref:`table.render_FOO`, the returned value from
        that method is used. If you want to differentiate between the rendered cell
        and a value, use a `value_Foo`-method::

            class Table(tables.Table):
                name = tables.Column()

                def render_name(self, value):
                    return format_html('<span class="name">{}</span>', value)

                def value_name(self, value):
                    return value

        will have a value wrapped in `<span>` in the rendered HTML, and just returns
        the value when `as_values()` is called.
        Nc                s   |  j  j r d S|  j   k S)NT)rv   Zexclude_from_exportr)   )rv   )exclude_columnsr   r   excluded  s    z%TableBase.as_values.<locals>.excludedc                s1   g  |  ]' }   |  s t  | j d  d  q S)strings_onlyT)r	   header)re   rv   )r{   r   r   
<listcomp>  s   	z'TableBase.as_values.<locals>.<listcomp>c                s:   g  |  ]0 }   |  s t   j | j  d  d  q S)r|   T)r	   Zget_cell_valuer)   )re   rv   )r{   rowr   r   r~     s   	)r   rl   ra   )r]   rz   r   )rz   r{   r   r   	as_values  s    	zTableBase.as_valuesc             C   s#   |  j  o" t d d   |  j D  S)z{
        Returns True if any of the columns define a ``_footer`` attribute or a
        ``render_footer()`` method
        c             s   s   |  ] } | j    Vq d  S)N)
has_footer)re   rv   r   r   r   rf     s    z'TableBase.has_footer.<locals>.<genexpr>)rm   anyr   )r]   r   r   r   r     s    zTableBase.has_footerc             C   s    |  j  d  k	 r |  j  S|  j j S)N)_show_headerr   rR   )r]   r   r   r   rR     s    zTableBase.show_headerc             C   s   | |  _  d  S)N)r   )r]   valuer   r   r   rR     s    c             C   s   |  j  S)N)rs   )r]   r   r   r   rI     s    zTableBase.order_byc             C   s   | s f  n | } t  | t j  r3 | j d  n | } g  } xL | D]D } t |  j } | |  j k rF |  j | j rF | j |  qF qF Wt	 |  |  _
 |  j j |  j
  d S)z
        Order the rows of the table based on columns.

        Arguments:
            value: iterable or comma separated string of order by aliases.
        ,N)r    r   rY   splitr   Zbarer   rT   r!   r   rs   r`   rI   )r]   r   rI   Zvalidaliasr)   r   r   r   rI     s    	'c             C   s    |  j  d  k	 r |  j  S|  j j S)N)_order_by_fieldr   rJ   )r]   r   r   r   rJ     s    zTableBase.order_by_fieldc             C   s   | |  _  d  S)N)r   )r]   r   r   r   r   rJ     s    c             C   s    |  j  d  k	 r |  j  S|  j j S)N)_page_fieldr   rK   )r]   r   r   r   rK     s    zTableBase.page_fieldc             C   s   | |  _  d  S)N)r   )r]   r   r   r   r   rK     s    r
   c             O   sF   | p |  j  j } | |  j | | |  |  _ |  j j |  |  _ d S)a  
        Paginates the table using a paginator and creates a ``page`` property
        containing information for the current page.

        Arguments:
            klass (`~django.core.paginator.Paginator`): A paginator class to
                paginate the results.

            per_page (int): Number of records to display on each page.
            page (int): Page to display.

        Extra arguments are passed to the paginator.

        Pagination exceptions (`~django.core.paginator.EmptyPage` and
        `~django.core.paginator.PageNotAnInteger`) may be raised from this
        method and should be handled by the caller.
        N)r   rM   rl   Z	paginatorrL   )r]   klassrM   rL   argskwargsr   r   r   paginate  s    zTableBase.paginatec             C   s    |  j  d  k	 r |  j  S|  j j S)N)_per_page_fieldr   rO   )r]   r   r   r   rO     s    zTableBase.per_page_fieldc             C   s   | |  _  d  S)N)r   )r]   r   r   r   r   rO     s    c             C   s    |  j  d  k	 r |  j  S|  j j S)N)_prefixr   rP   )r]   r   r   r   rP     s    zTableBase.prefixc             C   s   | |  _  d  S)N)r   )r]   r   r   r   r   rP     s    c             C   s   d |  j  |  j f S)Nz%s%s)rP   rJ   )r]   r   r   r   prefixed_order_by_field!  s    z!TableBase.prefixed_order_by_fieldc             C   s   d |  j  |  j f S)Nz%s%s)rP   rK   )r]   r   r   r   prefixed_page_field%  s    zTableBase.prefixed_page_fieldc             C   s   d |  j  |  j f S)Nz%s%s)rP   rO   )r]   r   r   r   prefixed_per_page_field)  s    z!TableBase.prefixed_per_page_fieldc             C   s   |  j  S)N)rr   )r]   r   r   r   rS   -  s    zTableBase.sequencec             C   s8   | r+ t  |  } | j |  j j    n  | |  _ d  S)N)r   rq   r   r-   rr   )r]   r   r   r   r   rS   1  s    c             C   s$   |  j  d  k	 r |  j  S|  j j Sd  S)N)
_orderabler   rT   )r]   r   r   r   rT   8  s    zTableBase.orderablec             C   s   | |  _  d  S)N)r   )r]   r   r   r   r   rT   ?  s    c             C   s$   |  j  d  k	 r |  j  S|  j j Sd  S)N)	_templater   rV   )r]   r   r   r   rV   C  s    zTableBase.template_namec             C   s   | |  _  d  S)N)r   )r]   r   r   r   r   rV   J  s    c             C   s   | j  | j  | S)a  
        Returns a set of HTML class names for cells (both td and th) of a
        **bound column** in this table.
        By default this returns the column class names defined in the table's
        attributes, and additionally the bound column's name.
        This method can be overridden to change the default behavior, for
        example to simply `return classes_set`.

        Arguments:
            classes_set(set of string): a set of class names to be added
              to the cell, retrieved from the column's attributes. In the case
              of a header cell (th), this also includes ordering classes.
              To set the classes for a column, see `.Column`.
              To configure ordering classes, see :ref:`ordering-class-name`

            bound_column(`.BoundColumn`): the bound column the class names are
              determined for. Useful for accessing `bound_column.name`.

        Returns:
            A set of class names to be added to cells of this column
        )addr)   )r]   Zclasses_setZbound_columnr   r   r   get_column_class_namesN  s    z TableBase.get_column_class_names)r?   r@   rA   rB   rW   rj   rk   rw   ry   r   r   propertyrR   setterrI   rJ   rK   r   r   rO   rP   r   r   r   rS   rT   rV   r   r   r   )r>   r   r_      sF   B[-r_   c               @   s   e  Z d  Z e j Z d S)TableN)r?   r@   rA   r_   rB   r   r   r   r   r   i  s   r   c       
      C   s   i |  d 6} | d k	 r& | | d <n  | d k	 r? | | d <n  | d k	 rX | | d <n  t  f } t | d  r | j t  f } n  t t d  | |  } |  j t d  } i | d 6}	 t |  | | f |	  S)aR  

    Arguments:
        model (`~django.db.models.Model`): Model associated with the new table

        table (`.Table`): Base Table class used to create the new one

        fields (list of str): Fields displayed in tables

        exclude (list of str): Fields exclude in tables

        localize (list of str): Fields to localize
    r&   Nr'   r+   r.   r   r   )objectr$   r   ri   strr?   )
r&   ra   r'   r+   r.   r3   parentr   
class_nameZtable_class_attrsr   r   r   table_factoryq  s    	
r   )(
__future__r   rn   rZ   collectionsr   	itertoolsr   Zdjango.confr   Zdjango.core.paginatorr   Zdjango.template.loaderr   Zdjango.utilsr   Zdjango.utils.encodingr	   rQ   r   configr   r`   r   rl   r   utilsr   r   r   r   r   ri   r   r   r   r_   Zadd_metaclassr   r   r   r   r   r   <module>   s,   (R, 	