
^Q\J                 @   se  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 m Z d  d l m Z m Z m Z d  d l m Z m Z m Z d  d l m  Z  d  d l! m" Z" d  d l# m$ Z% m& Z& Gd d   d e'  Z( d d   Z) d d   Z* d d   Z+ d d   Z, d d   Z- d d   Z. d d    Z/ Gd! d"   d" e  Z0 d# d$   Z1 d d% d&  Z2 d d' d(  Z3 d) d*   Z4 d d+ d, d-  Z5 d. d/   Z6 d0 d1   Z7 d+ d2 d3  Z8 Gd4 d5   d5 e'  Z9 d6 d7   Z: d8 d9   Z; d: d;   Z< d< d=   Z= d S)>    )unicode_literalsN)defaultdict)get_permission_codename)FieldDoesNotExist)models)
LOOKUP_SEP)	Collector)QUERY_TERMS)pretty_name)NoReverseMatchreverse)formatssixtimezone)	force_str
force_text
smart_text)format_html)capfirst)override	ungettextc               @   s   e  Z d  Z d Z d S)FieldIsAForeignKeyColumnNamez/A field is a foreign key attname, i.e. <FK>_id.N)__name__
__module____qualname____doc__ r   r   @/var/www/dbchiro/venv/build/Django/django/contrib/admin/utils.pyr      s   r   c             C   s   | j  t  } | d	 t k r2 | d d
  } n  x | D]x } | d k rZ |  j j } n  |  j |  } t | d  r9 | j   } | d j }  t	 d d   | D  r d Sq9 q9 Wd S)zU
    Returns True if 'distinct()' should be used to query the given lookup path.
       Npkget_path_infoc             s   s   |  ] } | j  Vq d  S)N)Zm2m).0pathr   r   r   	<genexpr>.   s    z(lookup_needs_distinct.<locals>.<genexpr>TFr$   r$   )
splitr   r	   r   name	get_fieldhasattrr    to_optsany)optsZlookup_pathZlookup_fields
field_namefieldZ	path_infor   r   r   lookup_needs_distinct   s    r.   c             C   sX   |  j  d  r! | j d  } n  |  j  d  rT | j   d	 k rK d } qT d } n  | S)
zK
    Returns a lookup value prepared to be used in queryset filtering.
    Z__in,Z__isnull false0FT)r0   zfalser2   )endswithr%   lower)keyvaluer   r   r   prepare_lookup_value4   s    		r7   c             C   sy   t  |  t j  s |  St |   } xG t t |   D]3 } | | } | d k r5 d t |  | | <q5 q5 Wd j |  S)a"  
    Ensure that primary key values do not confuse the admin URLs by escaping
    any '/', '_' and ':' and similarly problematic characters.
    Similar to urllib.quote, except that the quoting is slightly different so
    that it doesn't get automatically unquoted by the Web browser.
    z:/_#?;@&=+$,"[]<>%
\z_%02Xr0   )
isinstancer   string_typeslistrangelenordjoin)sresicr   r   r   quoteD   s    
rC   c             C   s   t  } t } |  j d  } | d g } | j } | d =x | D] } | d d  r y5 | | | | d d  d   | d d   Wq t k
 r | d |  Yq Xq? | d |  q? Wd j |  S)zI
    Undo the effects of quote(). Based heavily on urllib.unquote().
    _r   r      N   r0   )chrintr%   append
ValueErrorr>   )r?   ZmychrZmyatoir:   r@   Zmyappenditemr   r   r   unquoteU   s    	5rL   c             C   sM   g  } x@ |  D]8 } t  | t t f  r8 | j |  q | j |  q W| S)zNReturns a list which is a single level of flattening of the
    original list.)r8   r:   tupleextendrI   )fieldsZflatr-   r   r   r   flattenj   s    rP   c             C   s8   g  } x+ |  D]# \ } } | j  t | d   q W| S)z@Returns a list of field names from an admin fieldsets structure.rO   )rN   rP   )Z	fieldsetsfield_namesr&   r+   r   r   r   flatten_fieldsetsv   s
    rR   c       	         s   t  d |  } | j |   t        f d d    | j   }  f d d   | j D } d d   | j j   D } | |  | f S)a  
    Find all objects related to ``objs`` that should also be deleted. ``objs``
    must be a homogeneous iterable of objects (e.g. a QuerySet).

    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.
    usingc                s   |  j    j k } |  j } d t | j  t |   f } | r y; t d   j | j | j	 f d  t
 |  j    f  } Wn t k
 r | SYn Xd | j t d |  f }  j |  s  j | j  n  t d t | j  | |   S| Sd  S)Nz%s: %sz%s:%s_%s_changez%s.%sdeletez{}: <a href="{}">{}</a>)	__class__	_registry_metar   verbose_namer   r   r&   	app_label
model_namerC   Z_get_pk_valr   r   Zhas_permaddr   )objZ	has_adminr+   Zno_edit_linkZ	admin_urlp)
admin_siteperms_neededuserr   r   format_callback   s,    	
		z,get_deleted_objects.<locals>.format_callbackc                s   g  |  ] }   |   q Sr   r   )r!   r\   )ra   r   r   
<listcomp>   s   	 z'get_deleted_objects.<locals>.<listcomp>c             S   s+   i  |  ]! \ } } t  |  | j j  q Sr   )r<   rW   verbose_name_plural)r!   modelobjsr   r   r   
<dictcomp>   s   	 z'get_deleted_objects.<locals>.<dictcomp>)NestedObjectscollectsetnested	protected
model_objsitems)	re   r+   r`   r^   rS   Z	collectorZ	to_deleterk   Zmodel_countr   )r^   ra   r_   r`   r   get_deleted_objects   s    	 rn   c                   s   e  Z d  Z   f d d   Z d d   Z d d   f d d  Z   f d d	   Z d
 d   Z d d d  Z d d   Z	   S)rg   c                sA   t  t |   j | |   i  |  _ t   |  _ t t  |  _ d  S)N)superrg   __init__edgesri   rk   r   rl   )selfargskwargs)rU   r   r   rp      s    	zNestedObjects.__init__c             C   s    |  j  j | g   j |  d  S)N)rq   
setdefaultrI   )rr   sourcetargetr   r   r   add_edge   s    zNestedObjects.add_edgeNc                s   x | D] } | rc | j  d  rc | i | j j d 6| j j d 6} |  j t | |  |  n |  j d  |  |  j | j j j |  q Wy# t	 t
 |   j | d | | SWn; t j k
 r } z |  j j | j  WYd  d  } ~ Xn Xd  S)N+classrY   source_attr)r3   rW   rZ   rY   rx   getattrrl   rd   r[   ro   rg   rh   r   ZProtectedErrorrk   updateZprotected_objects)rr   re   rv   r{   rt   r\   related_namee)rU   r   r   rh      s    #zNestedObjects.collectc                s.   t  t |   j | |  } | j | j j  S)N)ro   rg   related_objectsZselect_relatedr-   r&   )rr   relatedre   qs)rU   r   r   r      s    zNestedObjects.related_objectsc             C   s   | | k r g  S| j  |  g  } x9 |  j j | f   D]" } | j |  j | | |   q9 W| rw | |  g } n	 | g } | r | j |  n  | S)N)r[   rq   getrN   _nestedrI   )rr   r\   seenra   childrenchildretr   r   r   r      s     	zNestedObjects._nestedc             C   sO   t    } g  } x9 |  j j d f   D]" } | j |  j | | |   q% W| S)z4
        Return the graph as a nested list.
        N)ri   rq   r   rN   r   )rr   ra   r   rootsrootr   r   r   rj      s
    	 zNestedObjects.nestedc             O   s   d S)z
        We always want to load the objects into memory so that we can display
        them to the user in confirm page.
        Fr   )rr   rs   rt   r   r   r   can_fast_delete   s    zNestedObjects.can_fast_delete)
r   r   r   rp   rx   rh   r   r   rj   r   r   r   )rU   r   rg      s   
rg   c             C   sx   t  |  t j t j j f  r* |  j } n* t  |  t j j  rN |  j j } n |  } i t	 | j
  d 6t	 | j  d 6S)z
    Return a `dict` with keys 'verbose_name' and 'verbose_name_plural',
    typically for use with string formatting.

    `obj` may be a `Model` instance, `Model` subclass, or `QuerySet` instance.
    rX   rc   )r8   r   ZModelbaseZ	ModelBaserW   queryQuerySetrd   r   rX   rc   )r\   r+   r   r   r   model_format_dict   s    r   c             C   ss   t  |  t j j  r< | d k r0 |  j   } n  |  j }  n  t |   } | d | d } } t | | | po d  S)a-  
    Return the appropriate `verbose_name` or `verbose_name_plural` value for
    `obj` depending on the count `n`.

    `obj` may be a `Model` instance, `Model` subclass, or `QuerySet` instance.
    If `obj` is a `QuerySet` instance, `n` is optional and the length of the
    `QuerySet` is used.
    NrX   rc   r   )r8   r   r   r   countrd   r   r   )r\   ndZsingularpluralr   r   r   model_ngettext  s    	r   c             C   s   | j  } y t | |   } Wn t t f k
 r t |   rS |  } | |  } n | d  k	 r t | |   r |  d k r |  d k r t | |   } | |  } n- t | |   } t |  r |   } n | } d  } Yn Xd  } t | |   } | | | f S)N__str____unicode__)rW   _get_non_gfk_fieldr   r   callabler(   r|   )r&   r\   model_adminr+   fattrr6   r   r   r   lookup_field  s*    	r   c             C   s   |  j  |  } | j r@ | j r+ | j s4 | j r@ t    n  | j r} | j r} t | d  r} | j | k r} t	    n  | S)a  
    For historical reasons, the admin app relies on GenericForeignKeys as being
    "not found" by get_field(). This could likely be cleaned up.

    Reverse relations should also be excluded as these aren't attributes of the
    model (rather something like `foo_set`).
    attname)
r'   is_relationZmany_to_onerelated_modelZone_to_manyr   Zmany_to_manyr(   r   r   )r+   r&   r-   r   r   r   r   5  s    	1r   Fc             C   s/  d } yG t  | j |   } y | j } Wn! t k
 rK | j j j } Yn XWnt k
 r|  d k r t | j j  } t j } nh|  d k r t	 | j j  } t
 } nAt |   r |  } n | d k	 r t | |   r t | |   } nc t | |   rt | |   } nB d |  | j j f } | rG| d | j j f 7} n  t |   t | d  rn| j } n t | t  rt | d  rt | j d  r| j j } nB t |  r| j d k rd	 } qt | j  } n t |   } Yn$ t k
 rt |   } |  } Yn X| r'| | f S| Sd S)
as  
    Returns a sensible label for a field name. The name can be a callable,
    property (but not created with @property decorator) or the name of an
    object's attribute, as well as a genuine fields. If return_attr is
    True, the resolved attribute (which could be a callable) is also returned.
    This will be None if (and only if) the name refers to a field.
    Nr   r   zUnable to lookup '%s' on %sz or %sshort_descriptionfgetz<lambda>z--)r   rW   rX   AttributeErrorr   r   r   r   	text_typer   bytesr   r(   r|   Zobject_namerU   r   r   r8   propertyr   r
   r   )r&   rd   r   Zreturn_attrr   r-   labelmessager   r   r   label_for_fieldJ  sR    			
r   c             C   s\   d } y t  | j |   } Wn t t f k
 r6 Yn Xt | d  rR | j } n  t |  S)Nr0   	help_text)r   rW   r   r   r(   r   r   )r&   rd   r   r-   r   r   r   help_text_for_field  s    r   c             C   sR  d d l  m } t | d d   r; t | j  j |  |  St | t j  s_ t | t j	  ri | |   S|  d  k ry | St | t j
  r t j t j |    St | t j t j f  r t j |   St | t j  r t j |  | j  St | t j t j f  rt j |   St | t j  rA|  rAt d |  j |   St |  |  Sd  S)Nr   )_boolean_iconflatchoicesz<a href="{}">{}</a>),django.contrib.admin.templatetags.admin_listr   r|   dictr   r   r8   r   ZBooleanFieldZNullBooleanFieldZDateTimeFieldr   localizer   template_localtimeZ	DateFieldZ	TimeFieldZDecimalFieldnumber_formatZdecimal_placesZIntegerFieldZ
FloatFieldZ	FileFieldr   urldisplay_for_value)r6   r-   empty_value_displayr   r   r   r   display_for_field  s$    $
r   c             C   s   d d l  m } | r  | |   S|  d  k r0 | St |  t j  rX t j t j |    St |  t j t j	 f  r t j |   St |  t
 j t j t f  r t j |   St |  t t f  r d j d d   |  D  St |   Sd  S)Nr   )r   z, c             s   s   |  ] } t  |  Vq d  S)N)r   )r!   vr   r   r   r#     s    z$display_for_value.<locals>.<genexpr>)r   r   r8   datetimer   r   r   r   datetimer   integer_typesdecimalZDecimalfloatr   r:   rM   r>   r   )r6   r   booleanr   r   r   r   r     s    
r   c               @   s   e  Z d  Z d S)NotRelationFieldN)r   r   r   r   r   r   r   r     s   r   c             C   s-   t  |  d  r# |  j   d j j St  d  S)Nr    r   r$   )r(   r    r)   rd   r   )r-   r   r   r   get_model_from_relation  s    r   c             C   s   g  } |  } | j  t  } x | D] } | j j |  } t |  t |  d k r} y t |  Wq} t k
 ry PYq} Xn  | j r | j o | j	 r | j
   } | j j } n | j j } | j } | j d |  q" W| t j |  f S)z Create a reversed field path.

    E.g. Given (Order, "user__groups"),
    return (Group, "user__order").

    Final field must be a related model, not a data field.
    r   r   )r%   r   rW   r'   r<   r   r   r   Zauto_createdZconcreteZrelated_query_nameZremote_fieldrd   r-   r&   r   insertr>   )rd   r"   Zreversed_pathparentpiecespiecer-   r~   r   r   r   reverse_field_path  s"    		r   c             C   sb   | j  t  } g  } xF | D]> } | r; t | d  } n |  } | j | j j |   q W| S)a;   Return list of Fields given path relative to model.

    e.g. (ModelX, "user__groups__name") -> [
        <django.db.models.fields.related.ForeignKey object at 0x...>,
        <django.db.models.fields.related.ManyToManyField object at 0x...>,
        <django.db.models.fields.CharField object at 0x...>,
    ]
    r   r$   )r%   r   r   rI   rW   r'   )rd   r"   r   rO   r   r   r   r   r   get_fields_from_path  s    	r   c       	      C   sc  g  } | r# | j  i i  d 6 n* |  j rM | j  i i |  j d 6d 6 n  | r_t d   x | D] } xE | j D]: } | j  i i t | j j  d 6t |  d 6d 6 qw WxR | j D]G \ } } | j  i i t | j j  d 6t |  d 6| d 6d 6 q WxE | j D]: } | j  i i t | j j  d 6t |  d 6d 6 qWqg WWd QXn  | S)z
    Construct a JSON structure describing changes from a changed object.
    Translations are deactivated so that strings are stored untranslated.
    Translation happens later on LogEntry access.
    addedrO   changedNr&   objectZdeleted)	rI   Zchanged_datatranslation_overrideZnew_objectsr   rW   rX   Zchanged_objectsZdeleted_objects)	formZformsetsr[   Zchange_messageZformsetZadded_objectZchanged_objectZchanged_fieldsZdeleted_objectr   r   r   construct_change_message  s2    	!			&r   )>
__future__r   r   r   collectionsr   Zdjango.contrib.authr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.models.constantsr   Zdjango.db.models.deletionr   Zdjango.db.models.sql.constantsr	   Zdjango.forms.utilsr
   Zdjango.urlsr   r   Zdjango.utilsr   r   r   Zdjango.utils.encodingr   r   r   Zdjango.utils.htmlr   Zdjango.utils.textr   Zdjango.utils.translationr   r   r   	Exceptionr   r.   r7   rC   rL   rP   rR   rn   rg   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sL   
4?;