B
    ¢0H[=H  ã               @   sŒ  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 d dlmZ d dlmZ d dlmZmZ G d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(G dd „ d eƒZ)d!d"„ Z*d<d#d$„Z+d=d%d&„Z,d'd(„ Z-d>d*d+„Z.d,d-„ Z/d.d/„ Z0d?d0d1„Z1G d2d3„ d3e ƒZ2d4d5„ Z3d6d7„ Z4d8d9„ Z5d:d;„ Z6dS )@é    N)Údefaultdict)Úget_permission_codename)ÚFieldDoesNotExist)Úmodels)Ú
LOOKUP_SEP)Ú	Collector)ÚQUERY_TERMS)Úpretty_name)ÚNoReverseMatchÚreverse)ÚformatsÚtimezone)Úformat_html)Úcapfirst)ÚngettextÚoverridec               @   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   ú^C:\Users\HIRONO~1\AppData\Local\Temp\pip-install-6bm3nxem\django\django\contrib\admin\utils.pyr      s   r   c             C   s€   |  t¡}|d tkr"|dd… }xX|D ]P}|dkr<| jj}|  |¡}t|dƒr(| ¡ }|d j} t	dd„ |D ƒƒr(dS q(W dS )	zT
    Return 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>TF)
Ú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   s8   |   d¡r| d¡}|   d¡r4| ¡ dkr0d}nd}|S )zJ
    Return a lookup value prepared to be used in queryset filtering.
    Z__inú,Z__isnull)Ú ÚfalseÚ0FT)Úendswithr   Úlower)ÚkeyÚvaluer   r   r   Úprepare_lookup_value/   s    


r1   c             C   sV   t | tƒs| S t| ƒ}x4tt|ƒƒD ]$}|| }|dkr$dt|ƒ ||< q$W d |¡S )a*  
    Ensure that primary key values do not confuse the admin URLs by escaping
    any '/', '_' and ':' and similarly problematic characters.
    Similar to urllib.parse.quote(), except that the quoting is slightly
    different so that it doesn't get automatically unquoted by the Web browser.
    z:/_#?;@&=+$,"[]<>%
\z_%02Xr*   )Ú
isinstanceÚstrÚlistÚrangeÚlenÚordÚjoin)ÚsÚresÚiÚcr   r   r   Úquote?   s    
r=   c          	   C   s¦   t }t}|  d¡}|d g}|j}|d= xr|D ]j}|dd… rŒy*||||dd… dƒƒ|dd…  ƒ W q˜ tk
rˆ   |d| ƒ Y q˜X q.|d| ƒ q.W d |¡S )zEUndo the effects of quote(). Based heavily on urllib.parse.unquote().Ú_r   é   é   Né   r*   )ÚchrÚintr   ÚappendÚ
ValueErrorr8   )r9   ZmychrZmyatoir4   r:   ZmyappendÚitemr   r   r   ÚunquoteP   s    


*rG   c             C   s:   g }x0| D ](}t |ttfƒr(| |¡ q
| |¡ q
W |S )zS
    Return a list which is a single level of flattening of the original list.
    )r2   r4   ÚtupleÚextendrD   )ÚfieldsZflatr'   r   r   r   Úflattenc   s    
rK   c             C   s,   g }x"| D ]\}}|  t|d ƒ¡ q
W |S )z?Return a list of field names from an admin fieldsets structure.rJ   )rI   rK   )Z	fieldsetsÚfield_namesr    r%   r   r   r   Úflatten_fieldsetsp   s
    rM   c       	         sh   t |d�}| | ¡ tƒ ‰‡ ‡‡fdd„‰| ˆ¡}‡fdd„|jD ƒ}dd„ |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).

    Return 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ƒ| f }|r¤y(tdˆ j|j|jf d t	| j
ƒfƒ}W n tk
rd   |S X d|jtd|ƒf }ˆ |¡s�ˆ |j¡ tdt|jƒ|| ƒS |S d S )Nz%s: %sz%s:%s_%s_changez%s.%sÚdeletez{}: <a href="{}">{}</a>)Ú	__class__Ú	_registryÚ_metar   Úverbose_namer   r    Ú	app_labelÚ
model_namer=   r   r
   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S r   r   )r   rW   )r\   r   r   ú
<listcomp>§   s    z'get_deleted_objects.<locals>.<listcomp>c             S   s   i | ]\}}t |ƒ|jj“qS r   )r6   rR   Úverbose_name_plural)r   ÚmodelÚobjsr   r   r   ú
<dictcomp>¨   s    z'get_deleted_objects.<locals>.<dictcomp>)ÚNestedObjectsÚcollectÚsetÚnestedÚ	protectedÚ
model_objsÚitems)	r`   r%   r[   rY   rN   Z	collectorZ	to_deleterf   Zmodel_countr   )rY   r\   rZ   r[   r   Úget_deleted_objectsz   s    


ri   c                   sX   e Zd Z‡ fdd„Zdd„ Zd‡ fdd„	Z‡ fdd	„Zd
d„ Zddd„Zdd„ Z	‡  Z
S )rb   c                s*   t ƒ j||Ž i | _tƒ | _ttƒ| _d S )N)ÚsuperÚ__init__Úedgesrd   rf   r   rg   )ÚselfÚargsÚkwargs)rP   r   r   rk   ®   s    zNestedObjects.__init__c             C   s   | j  |g ¡ |¡ d S )N)rl   Ú
setdefaultrD   )rm   ÚsourceÚtargetr   r   r   Úadd_edge´   s    zNestedObjects.add_edgeNc          
      s¶   xd|D ]\}|rB|  d¡sB||jj|jjdœ }|  t||ƒ|¡ n|  d |¡ | j|jj  |¡ qW yt	ƒ j
|fd|i|—ŽS  tjk
r° } z| j |j¡ W d d }~X Y nX d S )Nú+)ÚclassrT   Úsource_attr)r-   rR   rU   rT   rs   Úgetattrrg   r_   rV   rj   rc   r   ZProtectedErrorrf   ÚupdateZprotected_objects)rm   r`   rq   rv   ro   rW   Úrelated_nameÚe)rP   r   r   rc   ·   s    
zNestedObjects.collectc                s   t ƒ  ||¡}| |jj¡S )N)rj   Úrelated_objectsZselect_relatedr'   r    )rm   Úrelatedr`   Úqs)rP   r   r   r{   Ç   s    zNestedObjects.related_objectsc             C   sn   ||krg S |  |¡ g }x*| j |d¡D ]}| |  |||¡¡ q*W |rV||ƒg}n|g}|rj| |¡ |S )Nr   )rV   rl   ÚgetrI   Ú_nestedrD   )rm   rW   Úseenr\   ÚchildrenÚchildÚretr   r   r   r   Ë   s    

zNestedObjects._nestedc             C   s:   t ƒ }g }x*| j dd¡D ]}| |  |||¡¡ qW |S )z4
        Return the graph as a nested list.
        Nr   )rd   rl   r~   rI   r   )rm   r\   r€   ÚrootsÚrootr   r   r   re   Ú   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   )rm   rn   ro   r   r   r   Úcan_fast_deleteä   s    zNestedObjects.can_fast_delete)NN)N)r   r   r   rk   rs   rc   r{   r   re   r†   Ú__classcell__r   r   )rP   r   rb   ­   s   

rb   c             C   sF   t | tjtjjfƒr| j}nt | tjjƒr4| jj}n| }|j	|j
dœS )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.
    )rS   r^   )r2   r   ZModelÚbaseZ	ModelBaserR   ÚqueryÚQuerySetr_   rS   r^   )rW   r%   r   r   r   Úmodel_format_dictì   s    
r‹   c             C   sN   t | tjjƒr$|dkr|  ¡ }| j} t| ƒ}|d |d  }}t|||pJdƒ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.
    NrS   r^   r   )r2   r   r‰   rŠ   Úcountr_   r‹   r   )rW   ÚnÚdZsingularÚpluralr   r   r   Úmodel_ngettextÿ   s    	r�   c          	   C   s¬   |j }yt|| ƒ}W n~ ttfk
r’   t| ƒr>| }||ƒ}nL|d k	rlt|| ƒrl| dkrlt|| ƒ}||ƒ}nt|| ƒ}t|ƒr†|ƒ }n|}d }Y nX d }t|| ƒ}|||fS )NÚ__str__)rR   Ú_get_non_gfk_fieldr   r   Úcallabler"   rw   )r    rW   Úmodel_adminr%   ÚfÚattrr0   r   r   r   Úlookup_field  s$    





r—   c             C   sR   |   |¡}|jr(|jr|jr"|jr(tƒ ‚|jrN|jsNt|dƒrN|j|krNt	ƒ ‚|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’   +  s    
 r’   Fc             C   sŠ  d}y<t |j| ƒ}y
|j}W n tk
r:   |jjj}Y nX W �n2 tk
�rR   | dkrlt|jjƒ}t}nât| ƒrz| }nb|dk	r˜t|| ƒr˜t	|| ƒ}nDt|| ƒr®t	|| ƒ}n.d| |jj
f }|rÔ|d|jjf 7 }t|ƒ‚t|dƒrî|j}n`t|tƒ�rt|dƒ�rt|jdƒ�r|jj}n0t|ƒ�rF|jdk�r:d}n
t|jƒ}nt| ƒ}Y n" tk
�rr   t| ƒ}| }Y nX |�r‚||fS |S dS )	ak  
    Return 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 model field. If return_attr is True, also
    return the resolved attribute (which could be a callable). This will be
    None if (and only if) the name refers to a field.
    Nr‘   zUnable to lookup '%s' on %sz or %sÚshort_descriptionÚfgetz<lambda>z--)r’   rR   rS   ÚAttributeErrorrš   r   r3   r“   r"   rw   Zobject_namerP   r   r›   r2   Úpropertyrœ   r	   r   )r    r_   r”   Zreturn_attrr–   r'   ÚlabelÚmessager   r   r   Úlabel_for_field@  sL    





r¡   c          	   C   sB   d}yt |j| ƒ}W n ttfk
r,   Y nX t|dƒr>|j}|S )Nr*   Ú	help_text)r’   rR   r   r   r"   r¢   )r    r_   r¢   r'   r   r   r   Úhelp_text_for_fieldx  s    
r£   c             C   sê   ddl m} t|dd ƒr*t|jƒ | |¡S t|tjtj	fƒrD|| ƒS | d krP|S t|tj
ƒrlt t | ¡¡S t|tjtjfƒrˆt | ¡S t|tjƒr¢t | |j¡S t|tjtjfƒr¾t | ¡S t|tjƒrÜ| rÜtd| j| ƒS t| |ƒS d S )Nr   )Ú_boolean_iconÚflatchoicesz<a href="{}">{}</a>)Ú,django.contrib.admin.templatetags.admin_listr¤   rw   Údictr¥   r~   r2   r   ZBooleanFieldZNullBooleanFieldZDateTimeFieldr   Úlocalizer   Útemplate_localtimeZ	DateFieldZ	TimeFieldZDecimalFieldÚnumber_formatZdecimal_placesZIntegerFieldZ
FloatFieldZ	FileFieldr   ÚurlÚdisplay_for_value)r0   r'   Úempty_value_displayr¤   r   r   r   Údisplay_for_field„  s$    

r®   c             C   s¦   ddl m} |r|| ƒS | d kr$|S t| tjƒr@t t | ¡¡S t| tjtj	fƒr\t | ¡S t| t
tjtfƒrxt | ¡S t| ttfƒršd dd„ | D ƒ¡S t| ƒS d S )Nr   )r¤   z, c             s   s   | ]}t |ƒV  qd S )N)r3   )r   Úvr   r   r   r   «  s    z$display_for_value.<locals>.<genexpr>)r¦   r¤   r2   Údatetimer   r¨   r   r©   ÚdateÚtimerC   ÚdecimalÚDecimalÚfloatrª   r4   rH   r8   r3   )r0   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|  ¡ d jjS t‚d S )Nr   r   )r"   r   r#   r_   r·   )r'   r   r   r   Úget_model_from_relation´  s    
r¸   c          	   C   s°   g }| }|  t¡}xŽ|D ]†}|j |¡}t|ƒt|ƒd kr`yt|ƒ W n tk
r^   P Y nX |jr„|jrr|j	r„| 
¡ }|jj}n|jj}|j}| d|¡ qW |t |¡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   rR   r!   r6   r¸   r·   r™   Zauto_createdZconcreteZrelated_query_nameZremote_fieldr_   r'   r    rš   Úinsertr8   )r_   r   Zreversed_pathÚparentÚpiecesÚpiecer'   ry   r   r   r   Úreverse_field_path»  s"    


r½   c             C   sH   |  t¡}g }x4|D ],}|r*t|d ƒ}n| }| |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¸   rD   rR   r!   )r_   r   r»   rJ   r¼   rº   r   r   r   Úget_fields_from_pathÚ  s    	

r¾   c       	   
   C   sò   g }|r|  di i¡ n| jr2|  dd| jii¡ |rîtdƒ�ª x¢|D ]š}x.|jD ]$}|  dt|jjƒt|ƒdœi¡ qRW x4|jD ]*\}}|  dt|jjƒt|ƒ|dœi¡ q‚W x.|jD ]$}|  dt|jjƒt|ƒdœi¡ q¸W qFW W dQ R X |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.
    ÚaddedÚchangedrJ   N)r    Úobject)r    rÁ   rJ   Zdeleted)	rD   Zchanged_dataÚtranslation_overrideZnew_objectsr3   rR   rS   Zchanged_objectsZdeleted_objects)	ÚformZformsetsrV   Zchange_messageZformsetZadded_objectZchanged_objectZchanged_fieldsZdeleted_objectr   r   r   Úconstruct_change_messageî  s2    




"rÄ   )N)N)NF)F)7r°   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   Zdjango.utils.htmlr   Zdjango.utils.textr   Zdjango.utils.translationr   r   rÂ   Ú	Exceptionr   r(   r1   r=   rG   rK   rM   ri   rb   r‹   r�   r—   r’   r¡   r£   r®   r¬   r·   r¸   r½   r¾   rÄ   r   r   r   r   Ú<module>   sH   
3?


8
