
TQc           @  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 m Z m Z d  d l m Z d  d l m Z d  d l m Z d   Z d   Z d   Z  d   Z! d   Z" d   Z# d e	 f d     YZ$ d   Z% d d  Z' d d  Z( d e) d  Z* d   Z+ d   Z, e) d  Z- d e. f d      YZ/ d!   Z0 d"   Z1 d#   Z2 d$   Z3 d%   Z4 d S(&   i(   t   unicode_literalsN(   t   models(   t
   LOOKUP_SEP(   t	   Collector(   t   RelatedObject(   t   pretty_name(   t   formats(   t   format_html(   t   capfirst(   t   timezone(   t	   force_strt
   force_textt
   smart_text(   t   six(   t	   ungettext(   t   reversec         C  sw   | j  d d  d } |  j |  d } t | d  rM t | j t j  so t | t j j  rs | j	 j
 rs t St S(   uU   
    Returns True if 'distinct()' should be used to query the given lookup path.
    u   __i   i    u   rel(   t   splitt   get_field_by_namet   hasattrt
   isinstancet   relR   t   ManyToManyRelt   relatedR   t   fieldt   uniquet   Truet   False(   t   optst   lookup_patht
   field_nameR   (    (    s2   ../Django//lib/python/django/contrib/admin/util.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   false(   u    u   false(   t   endswithR   t   lowerR   R   (   t   keyt   value(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   prepare_lookup_value!   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    (   R   R   t   string_typest   listt   ranget   lent   ordt   join(   t   st   rest   it   c(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   quote0   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
   ValueErrorR)   (   R*   t   mychrt   myatoiR%   R+   t   myappendt   item(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   unquoteA   s    	)c         C  se   g  } xX |  D]P \ } } xA | d D]5 } t  |  t k rL | j |  q$ | j |  q$ Wq W| S(   u@   Returns a list of field names from an admin fieldsets structure.u   fields(   t   typet   tuplet   extendR1   (   t	   fieldsetst   field_namest   nameR   R   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   flatten_fieldsetsV   s    c   
        sx   t  d |  } | j |   t         f d   } | j |  } g  | j D] } | |  ^ qS }	 |   |	 f S(   u  
    Find all objects related to ``objs`` that should also be deleted. ``objs``
    must be a homogenous 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 } | r t d  j | j | j j   f d  t	 |  j
    f  } d | j | j   f }  j |  s   j | j  n  t d t | j  | |   Sd t | j  t |   f Sd  S(   Nu   %s:%s_%s_changeu   %s.%su   {0}: <a href="{1}">{2}</a>u   %s: %s(   t	   __class__t	   _registryt   _metaR   R=   t	   app_labelt   object_nameR    t   NoneR.   t   _get_pk_valt   get_delete_permissiont   has_permt   addt   verbose_nameR   R   R   (   t   objt	   has_adminR   t	   admin_urlt   p(   t   perms_neededt   usert
   admin_site(    s2   ../Django//lib/python/django/contrib/admin/util.pyt   format_callbackp   s$    		(   t   NestedObjectst   collectt   sett   nestedt	   protected(
   t   objsR   RP   RQ   R?   t	   collectorRR   t	   to_deleteRK   RW   (    (   RO   RP   RQ   s2   ../Django//lib/python/django/contrib/admin/util.pyt   get_deleted_objectsc   s    		"RS   c           B  sM   e  Z d    Z d   Z d d  Z d   Z d   Z d d  Z d   Z	 RS(   c         O  s2   t  t |   j | |   i  |  _ t   |  _ d  S(   N(   t   superRS   t   __init__t   edgesRU   RW   (   t   selft   argst   kwargs(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyR]      s    	c         C  s    |  j  j | g   j |  d  S(   N(   R^   t
   setdefaultR1   (   R_   t   sourcet   target(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   add_edge   s    c         K  s   x@ | D]8 } | r/ |  j  t | |  |  q |  j  d  |  q Wy# t t |   j | d | | SWn) t j k
 r } |  j j	 | j
  n Xd  S(   Nt   source_attr(   Re   t   getattrRE   R\   RS   RT   R   t   ProtectedErrorRW   t   updatet   protected_objects(   R_   RX   Rf   Ra   RK   t   e(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyRT      s    #c         C  s.   t  t |   j | |  } | j | j j  S(   N(   R\   RS   t   related_objectst   select_relatedR   R=   (   R_   R   RX   t   qs(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyRl      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(    (   RI   R^   t   getR:   t   _nestedR1   (   R_   RK   t   seenRR   t   childrent   childt   ret(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyRp      s     	c         C  sO   t    } g  } x9 |  j j d d  D]" } | j |  j | | |   q% W| S(   u5   
        Return the graph as a nested list.

        N(    (   RU   R^   Ro   RE   R:   Rp   (   R_   RR   Rq   t   rootst   root(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyRV      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   (   R_   R`   Ra   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   can_fast_delete   s    N(
   t   __name__t
   __module__R]   Re   RE   RT   Rl   Rp   RV   Rw   (    (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyRS      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(   R   R   t   Modelt   baset	   ModelBaseRB   t   queryt   QuerySett   modelR   RJ   t   verbose_name_plural(   RK   R   (    (    s2   ../Django//lib/python/django/contrib/admin/util.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(	   R   R   R}   R~   RE   t   countR   R   R   (   RK   t   nt   dt   singulart   plural(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   model_ngettext   s    
c         C  s   | j  } y | j |   } Wn t j k
 r t |   rP |  } | |  } 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__(   RB   t	   get_fieldR   t   FieldDoesNotExistt   callableRE   R   Rg   (   R=   RK   t   model_adminR   t   ft   attrR"   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   lookup_field   s&    	
c         C  s  d	 } yA | j j |   d } t | t  r= | j j } n	 | j } Wngt j 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 } | rD| d | j j f 7} n  t |   t | d  rk| j } qt |  r| j d k rd } qt | j  } qt |   } n X| r| | f S| Sd	 S(
   u9  
    Returns a sensible label for a field name. The name can be a callable or the
    name of an object attributes, 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.
    i    u   __unicode__u   __str__u   Unable to lookup '%s' on %su    or %su   short_descriptionu   <lambda>u   --N(   RE   RB   R   R   R   R   RJ   R   R   R   R   t	   text_typeR
   t   bytesR   R   Rg   RD   R@   Rx   t   AttributeErrort   short_descriptionR   (   R=   R   R   t   return_attrR   R   t   labelt   message(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   label_for_field  sB    			
c         C  sD   y | j  j |   d j } Wn t j k
 r9 d } n Xt |  S(   Ni    u    (   RB   R   t	   help_textR   R   R   (   R=   R   R   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   help_text_for_field<  s
    
c         C  s"  d d l  m } d d l m } | j rB t | j  j |  |  St | t j	  sf t | t j
  rp | |   S|  d  k r | 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  rt j |   St |   Sd  S(   Ni(   t   _boolean_icon(   t   EMPTY_CHANGELIST_VALUE(   t,   django.contrib.admin.templatetags.admin_listR   t   django.contrib.admin.views.mainR   t   flatchoicest   dictRo   R   R   t   BooleanFieldt   NullBooleanFieldRE   t   DateTimeFieldR   t   localizeR	   t   template_localtimet	   DateFieldt	   TimeFieldt   DecimalFieldt   number_formatt   decimal_placest
   FloatFieldR   (   R"   R   R   R   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   display_for_fieldD  s"    	$
c         C  s   d d l  m } d d l m } | r0 | |   S|  d  k r@ | St |  t j  rh t j t	 j
 |    St |  t j t j f  r t j |   St |  t j t j t f  r t j |   St |   Sd  S(   Ni(   R   (   R   (   R   R   R   R   RE   R   t   datetimeR   R   R	   R   t   datet   timeR   t   integer_typest   decimalt   Decimalt   floatR   R   (   R"   t   booleanR   R   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   display_for_value\  s    
t   NotRelationFieldc           B  s   e  Z RS(    (   Rx   Ry   (    (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyR   n  s   c         C  s?   t  |  t j j  r |  j St |  d  r5 |  j j St  d  S(   Nu   rel(	   R   R   R   R   R   Rg   R   t   toR   (   R   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   get_model_from_relationr  s
    
c   
      C  s   g  } |  } | j  t  } x | D] } | j j |  \ } }  } } t |  t |  d k r y t |  Wq t k
 r Pq Xn  | 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   RB   R   R'   R   R   t   related_query_nameR   R   R   R=   R   t   insertR)   (
   R   t   patht   reversed_patht   parentt   piecest   pieceR   t   directt   m2mt   related_name(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   reverse_field_path{  s"    		c         C  sf   | j  t  } g  } xJ | D]B } | r; t | d  } n |  } | j | j j |  d  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...>,
    ]
    ii    (   R   R   R   R1   RB   R   (   R   R   R   t   fieldsR   R   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   get_fields_from_path  s    	!c         C  s4   y t  |  d  Wn t k
 r/ |  d  }  n X|  S(   u0    Discard trailing non-relation field if extant. i(   R   R   (   R   (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   remove_trailing_data_field  s
    c         C  s   t  |  |  } t |  } | oJ t | d d  oJ t | d j d d  } | s] t j   St | t j  rs | St j |   Sd S(   u    Return Q object for limiting choices if applicable.

    If final model in path is linked via a ForeignKey or ManyToManyField which
    has a `limit_choices_to` attribute, return it as a Q object.
    iu   relu   limit_choices_toN(	   R   R   R   Rg   R   RE   R   t   QR   (   R   R   R   t   limit_choices_to(    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   get_limit_choices_to_from_path  s    
(5   t
   __future__R    R   R   t	   django.dbR   t   django.db.models.constantsR   t   django.db.models.deletionR   t   django.db.models.relatedR   t   django.forms.formsR   t   django.utilsR   t   django.utils.htmlR   t   django.utils.textR   R	   t   django.utils.encodingR
   R   R   R   t   django.utils.translationR   t   django.core.urlresolversR   R   R#   R.   R7   R>   R[   RS   R   RE   R   R   R   R   R   R   R   t	   ExceptionR   R   R   R   R   R   (    (    (    s2   ../Django//lib/python/django/contrib/admin/util.pyt   <module>   sF   						-:	0								