
0_c           @  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 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& d e' f d     YZ( d   Z) d   Z* d   Z+ d   Z, d   Z- d   Z. d   Z/ d e f d     YZ0 d   Z1 d d  Z3 d d  Z4 d   Z5 d e6 d   Z7 d!   Z8 d"   Z9 e6 d#  Z: d$ e' f d%     YZ; d&   Z< d'   Z= d(   Z> d)   Z? d S(*   i(   t   unicode_literalsN(   t   defaultdict(   t   get_permission_codename(   t   FieldDoesNotExist(   t   models(   t
   LOOKUP_SEP(   t	   Collector(   t   QUERY_TERMS(   t   pretty_name(   t   NoReverseMatcht   reverse(   t   formatst   sixt   timezone(   t	   force_strt
   force_textt
   smart_text(   t   format_html(   t   capfirst(   t   overridet	   ungettextt   FieldIsAForeignKeyColumnNamec           B  s   e  Z d  Z RS(   u/   A field is a foreign key attname, i.e. <FK>_id.(   t   __name__t
   __module__t   __doc__(    (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyR      s   c         C  s   | j  t  } | d t k r, | d  } n  x} | D]u } | d k rT |  j j } n  |  j |  } t | d  r3 | j   } | d j }  t	 d   | D  r t
 Sq3 q3 Wt S(   uU   
    Returns True if 'distinct()' should be used to query the given lookup path.
    iu   pku   get_path_infoc         s  s   |  ] } | j  Vq d  S(   N(   t   m2m(   t   .0t   path(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pys	   <genexpr>.   s    (   t   splitR   R   t   pkt   namet	   get_fieldt   hasattrt   get_path_infot   to_optst   anyt   Truet   False(   t   optst   lookup_patht   lookup_fieldst
   field_namet   fieldt	   path_info(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   lookup_needs_distinct   s    c         C  sX   |  j  d  r! | j d  } n  |  j  d  rT | j   d k rK t } qT t } n  | S(   uK   
    Returns a lookup value prepared to be used in queryset filtering.
    u   __inu   ,u   __isnullu    u   falseu   0(   u    u   falseu   0(   t   endswithR   t   lowerR%   R$   (   t   keyt   value(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   prepare_lookup_value4   s    		c         C  sy   t  |  t j  s |  St |   } xG t t |   D]3 } | | } | d k r5 d t |  | | <q5 q5 Wd j |  S(   u"  
    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.
    u   :/_#?;@&=+$,"[]<>%
\u   _%02Xu    (   t
   isinstanceR   t   string_typest   listt   ranget   lent   ordt   join(   t   st   rest   it   c(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   quoteD   s    
c         C  s   t  } t } |  j d  } | d g } | j } | d =xw | D]o } | d d !r y) | | | | d  d   | d  Wq t k
 r | d |  q Xq? | d |  q? Wd j |  S(   uI   
    Undo the effects of quote(). Based heavily on urllib.unquote().
    u   _i    i   i   i   u    (   t   chrt   intR   t   appendt
   ValueErrorR8   (   R9   t   mychrt   myatoiR4   R:   t   myappendt   item(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   unquoteU   s    	)c         C  sM   g  } x@ |  D]8 } t  | t t f  r8 | j |  q | j |  q W| S(   uN   Returns a list which is a single level of flattening of the
    original list.(   R2   R4   t   tuplet   extendR@   (   t   fieldst   flatR*   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   flattenj   s    c         C  s8   g  } x+ |  D]# \ } } | j  t | d   q W| S(   u@   Returns a list of field names from an admin fieldsets structure.u   fields(   RH   RK   (   t	   fieldsetst   field_namesR   R&   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   flatten_fieldsetsv   s
    c           s   t  d |  } | j |   t        f d   } | j |  } g  | j D] } | |  ^ qS }	 d   | j j   D }
 | |
  |	 f S(   u  
    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.
    t   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 | SXd | j t d |  f }  j |  s  j | j  n  t d t | j  | |   S| Sd  S(   Nu   %s: %su   %s:%s_%s_changeu   %s.%su   deleteu   {}: <a href="{}">{}</a>(   t	   __class__t	   _registryt   _metaR   t   verbose_nameR   R
   R   t	   app_labelt
   model_namet   NoneR=   t   _get_pk_valR	   R   t   has_permt   addR   (   t   objt	   has_adminR&   t   no_edit_linkt	   admin_urlt   p(   t
   admin_sitet   perms_neededt   user(    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   format_callback   s,    	
	c         S  s+   i  |  ]! \ } } t  |  | j j  q S(    (   R6   RR   t   verbose_name_plural(   R   t   modelt   objs(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pys
   <dictcomp>   s   	 (   t   NestedObjectst   collectt   sett   nestedt	   protectedt
   model_objst   items(   Re   R&   Ra   R_   RO   t	   collectorRb   t	   to_deleteRZ   Rj   t   model_count(    (   R_   R`   Ra   s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   get_deleted_objects   s    	 "Rf   c           B  sP   e  Z d    Z d   Z d d d  Z d   Z d   Z d d  Z d   Z	 RS(   c         O  sA   t  t |   j | |   i  |  _ t   |  _ t t  |  _ d  S(   N(   t   superRf   t   __init__t   edgesRh   Rj   R   Rk   (   t   selft   argst   kwargs(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyRr      s    	c         C  s    |  j  j | g   j |  d  S(   N(   Rs   t
   setdefaultR@   (   Rt   t   sourcet   target(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   add_edge   s    c         K  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 } |  j j | j  n Xd  S(   Nu   +u   classu	   app_labelt   source_attr(   R-   RR   RU   RT   Rz   t   getattrRV   Rk   Rd   RY   Rq   Rf   Rg   R   t   ProtectedErrorRj   t   updatet   protected_objects(   Rt   Re   Rx   R{   Rv   RZ   t   related_namet   e(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyRg      s    #c         C  s.   t  t |   j | |  } | j | j j  S(   N(   Rq   Rf   t   related_objectst   select_relatedR*   R   (   Rt   t   relatedRe   t   qs(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyR      s    c         C  s   | | k r g  S| j  |  g  } x9 |  j j | d  D]" } | j |  j | | |   q9 W| rw | |  g } n	 | g } | r | j |  n  | S(   N(    (   RY   Rs   t   getRH   t   _nestedR@   (   Rt   RZ   t   seenRb   t   childrent   childt   ret(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyR      s     	c         C  sO   t    } g  } x9 |  j j d d  D]" } | j |  j | | |   q% W| S(   u4   
        Return the graph as a nested list.
        N(    (   Rh   Rs   R   RV   RH   R   (   Rt   Rb   R   t   rootst   root(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyRi      s
    	 c         O  s   t  S(   u   
        We always want to load the objects into memory so that we can display
        them to the user in confirm page.
        (   R%   (   Rt   Ru   Rv   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   can_fast_delete   s    N(
   R   R   Rr   Rz   RV   Rg   R   R   Ri   R   (    (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyRf      s   				
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(   u   
    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.
    u   verbose_nameu   verbose_name_plural(   R2   R   t   Modelt   baset	   ModelBaseRR   t   queryt   QuerySetRd   R   RS   Rc   (   RZ   R&   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   model_format_dict   s    c         C  ss   t  |  t j j  r< | d k r0 |  j   } n  |  j }  n  t |   } | d | d } } t | | | po d  S(   u-  
    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.
    u   verbose_nameu   verbose_name_plurali    N(	   R2   R   R   R   RV   t   countRd   R   R   (   RZ   t   nt   dt   singulart   plural(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   model_ngettext  s    	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  } n Xd  } t | |   } | | | f S(   Nu   __str__u   __unicode__(   RR   t   _get_non_gfk_fieldR   R   t   callableRV   R    R|   (   R   RZ   t   model_adminR&   t   ft   attrR0   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   lookup_field  s*    	
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(   u  
    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`).
    u   attname(
   R   t   is_relationt   many_to_onet   related_modelt   one_to_manyR   t   many_to_manyR    t   attnameR   (   R&   R   R*   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyR   5  s    	1c         C  s,  d	 } yF t | j |   } y | j } Wn  t k
 rJ | j j j } n XWnt k
 r|  d k r t | j j  } t j	 } q|  d k r t
 | j j  } t } qt |   r |  } n | d	 k	 r t | |   r t | |   } nc t | |   rt | |   } nB d |  | j j f } | rF| d | j j f 7} n  t |   t | d  rm| j } qt | t  rt | d  rt | j d  r| j j } qt |  r| j d k rd } qt | j  } qt |   } n# t k
 rt |   } |  } n X| r$| | f S| Sd	 S(
   us  
    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.
    u   __unicode__u   __str__u   Unable to lookup '%s' on %su    or %su   short_descriptionu   fgetu   <lambda>u   --N(   RV   R   RR   RS   t   AttributeErrorR   R   R   R   t	   text_typeR   t   bytesR   R    R|   t   object_nameRP   R   t   short_descriptionR2   t   propertyt   fgetR   R   (   R   Rd   R   t   return_attrR   R*   t   labelt   message(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   label_for_fieldJ  sR    			

c         C  s[   d } y t  | j |   } Wn t t f k
 r5 n Xt | d  rQ | j } n  t |  S(   Nu    u	   help_text(   R   RR   R   R   R    t	   help_textR   (   R   Rd   R   R*   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   help_text_for_field  s    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(   Ni(   t   _boolean_iconu   flatchoicesu   <a href="{}">{}</a>(   t,   django.contrib.admin.templatetags.admin_listR   R|   RV   t   dictt   flatchoicesR   R2   R   t   BooleanFieldt   NullBooleanFieldt   DateTimeFieldR   t   localizeR   t   template_localtimet	   DateFieldt	   TimeFieldt   DecimalFieldt   number_formatt   decimal_placest   IntegerFieldt
   FloatFieldt	   FileFieldR   t   urlt   display_for_value(   R0   R*   t   empty_value_displayR   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   display_for_field  s$    $
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  St |   Sd  S(   Ni(   R   u   , c         s  s   |  ] } t  |  Vq d  S(   N(   R   (   R   t   v(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pys	   <genexpr>  s    (   R   R   RV   R2   t   datetimeR   R   R   R   t   datet   timeR   t   integer_typest   decimalt   Decimalt   floatR   R4   RG   R8   R   (   R0   R   t   booleanR   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyR     s    
t   NotRelationFieldc           B  s   e  Z RS(    (   R   R   (    (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyR     s   c         C  s-   t  |  d  r# |  j   d j j St  d  S(   Nu   get_path_infoi(   R    R!   R"   Rd   R   (   R*   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   get_model_from_relation  s    c         C  s   g  } |  } | j  t  } x | D] } | j j |  } t |  t |  d k r| y t |  Wq| t k
 rx Pq| Xn  | j r | j o | j	 r | j
   } | j j } n | j j } | j } | j d |  q" W| t j |  f S(   u    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.
    i   i    (   R   R   RR   R   R6   R   R   R   t   auto_createdt   concretet   related_query_namet   remote_fieldRd   R*   R   R   t   insertR8   (   Rd   R   t   reversed_patht   parentt   piecest   pieceR*   R   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   reverse_field_path  s"    	c         C  sb   | j  t  } g  } xF | D]> } | r; t | d  } n |  } | j | j j |   q W| S(   u;   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...>,
    ]
    i(   R   R   R   R@   RR   R   (   Rd   R   R   RI   R   R   (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   get_fields_from_path  s    	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(   u   
    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.
    u   addedu   fieldsu   changedu   nameu   objectu   deletedN(
   R@   t   changed_datat   translation_overrideRV   t   new_objectsR   RR   RS   t   changed_objectst   deleted_objects(	   t   formt   formsetsRY   t   change_messaget   formsett   added_objectt   changed_objectt   changed_fieldst   deleted_object(    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   construct_change_message  s2    	!			&(@   t
   __future__R    R   R   t   collectionsR   t   django.contrib.authR   t   django.core.exceptionsR   t	   django.dbR   t   django.db.models.constantsR   t   django.db.models.deletionR   t   django.db.models.sql.constantsR   t   django.forms.utilsR   t   django.urlsR	   R
   t   django.utilsR   R   R   t   django.utils.encodingR   R   R   t   django.utils.htmlR   t   django.utils.textR   t   django.utils.translationR   R   R   t	   ExceptionR   R,   R1   R=   RF   RK   RN   Rp   Rf   R   RV   R   R   R   R%   R   R   R   R   R   R   R   R   R   (    (    (    s<   /tmp/pip-unpacked-wheel-BAJOf3/django/contrib/admin/utils.pyt   <module>   sL   						
	4?		;					