o
    —¨ÊhÉN  ã                   @   sÚ  d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZ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 d dlmZ d dlmZ dd„ dD ƒZ dd„ e  !¡ D ƒZ"edd #dd„ e"D ƒ¡ ƒZ$G dd„ de%ƒZ&dd„ Z'dGd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/dHd,d-„Z0dHd.d/„Z1d0d1„ Z2dId3d4„Z3d5d6„ Z4d7d8„ Z5dJd9d:„Z6G d;d<„ d<e%ƒZ7d=d>„ Z8d?d@„ Z9dAdB„ Z:dCdD„ Z;dEdF„ Z<dS )Ké    N)Údefaultdict)ÚFieldDoesNotExist)ÚmodelsÚrouter)Ú
LOOKUP_SEP)Ú	Collector)Úpretty_name)ÚNoReverseMatchÚreverse)ÚformatsÚtimezone)Úformat_html)Ú_lazy_re_compile)Úcapfirst)Úngettext)Úoverridec                 C   s   i | ]}|d | “qS )z_%02X© )Ú.0Úir   r   úL/var/www/html/env/lib/python3.10/site-packages/django/contrib/admin/utils.pyÚ
<dictcomp>   s    r   s   ":/_#?;@&=+$,"[]<>%
\c                 C   s   i | ]	\}}|t |ƒ“qS r   )Úchr)r   ÚkÚvr   r   r   r      s    z_(?:%s)ú|c                 C   s   g | ]}|d d… ‘qS )é   Nr   )r   Úxr   r   r   Ú
<listcomp>   s    r   c                   @   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   r   r   r      s    r   c              	   C   s|   |  t¡}|D ]4}|dkr| jj}z|  |¡}W n	 ty!   Y qw t|dƒr;|j}|d j} t	dd„ |D ƒƒr; dS qdS )zA
    Return True if the given lookup path spawns duplicates.
    ÚpkÚ
path_infoséÿÿÿÿc                 s   s   � | ]}|j V  qd S ©N)Úm2m)r   Úpathr   r   r   Ú	<genexpr>1   s   € z+lookup_spawns_duplicates.<locals>.<genexpr>TF)
Úsplitr   r#   ÚnameÚ	get_fieldr   Úhasattrr$   Úto_optsÚany)ÚoptsÚlookup_pathÚlookup_fieldsÚ
field_nameÚfieldÚ	path_infor   r   r   Úlookup_spawns_duplicates   s    
þ

€r6   ú,c                 C   s2   |   d¡r| |¡}|S |   d¡r| ¡ dv}|S )zJ
    Return a lookup value prepared to be used in queryset filtering.
    Ú__inÚ__isnull)Ú ÚfalseÚ0)Úendswithr*   Úlower)ÚkeyÚvalueÚ	separatorr   r   r   Úprepare_lookup_value8   s   


þrB   c                 C   s   t | tƒr
|  t¡S | 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.
    )Ú
isinstanceÚstrÚ	translateÚ	QUOTE_MAP©Úsr   r   r   ÚquoteE   s   rI   c                 C   s   t  dd„ | ¡S )zUndo the effects of quote().c                 S   s   t | d  S )Nr   )ÚUNQUOTE_MAP)Úmr   r   r   Ú<lambda>Q   s    zunquote.<locals>.<lambda>)Ú
UNQUOTE_REÚsubrG   r   r   r   ÚunquoteO   s   rO   c                 C   s6   g }| D ]}t |ttfƒr| |¡ q| |¡ q|S )zS
    Return a list which is a single level of flattening of the original list.
    )rC   ÚlistÚtupleÚextendÚappend)ÚfieldsÚflatr4   r   r   r   ÚflattenT   s   rV   c                 C   s(   g }| D ]\}}|  t|d ƒ¡ q|S )z?Return a list of field names from an admin fieldsets structure.rT   )rR   rV   )Ú	fieldsetsÚfield_namesr+   r0   r   r   r   Úflatten_fieldsetsa   s   rY   c           	         s¦   z| d }W n t y   g i tƒ g f Y S w t |jj¡}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.
    r   )ÚusingÚoriginc                    s¢   | j }|ˆ jv }| j}dt|jƒ| f }|rOˆ j|  ˆ| ¡s%ˆ |j¡ ztdˆ j|j	|j
f d t| jƒfƒ}W n tyD   | Y S w tdt|jƒ|| ƒS |S )Nz%s: %sz%s:%s_%s_changez{}: <a href="{}">{}</a>)Ú	__class__Ú	_registryÚ_metar   Úverbose_nameÚhas_delete_permissionÚaddr
   r+   Ú	app_labelÚ
model_namerI   r#   r	   r   )ÚobjÚmodelÚ	has_adminr0   Úno_edit_linkÚ	admin_url)Ú
admin_siteÚperms_neededÚrequestr   r   Úformat_callback{   s,   
ÿ
üþÿz,get_deleted_objects.<locals>.format_callbackc                    s   g | ]}ˆ |ƒ‘qS r   r   )r   rd   )rl   r   r   r   ›   s    z'get_deleted_objects.<locals>.<listcomp>c                 S   s   i | ]\}}|j jt|ƒ“qS r   )r^   Úverbose_name_pluralÚlen)r   re   Úobjsr   r   r   r   œ   s    ÿÿz'get_deleted_objects.<locals>.<dictcomp>)Ú
IndexErrorÚsetr   Údb_for_writer^   re   ÚNestedObjectsÚcollectÚnestedÚ	protectedÚ
model_objsÚitems)	ro   rk   ri   rd   rZ   Ú	collectorÚ	to_deleterv   Úmodel_countr   )ri   rl   rj   rk   r   Úget_deleted_objectsi   s    ÿ

þr|   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 )rs   c                    s.   t ƒ j|i |¤Ž i | _tƒ | _ttƒ| _d S r&   )ÚsuperÚ__init__Úedgesrq   rv   r   rw   ©ÚselfÚargsÚkwargs©r\   r   r   r~   ¥   s   zNestedObjects.__init__c                 C   s   | j  |g ¡ |¡ d S r&   )r   Ú
setdefaultrS   )r�   ÚsourceÚtargetr   r   r   Úadd_edge«   s   zNestedObjects.add_edgeNc              
      sè   |D ].}|r |  d¡s ||jj|jjdœ }|  t||ƒ|¡ n|  d |¡ | j|jj  |¡ qzt	ƒ j
|fd|i|¤ŽW S  tjyY } z| j |j¡ W Y d }~d S d }~w tjys } z| j |j¡ W Y d }~d S d }~ww )Nú+)Úclassrb   Úsource_attr)r=   r^   rc   rb   rˆ   Úgetattrrw   re   ra   r}   rt   r   ÚProtectedErrorrv   ÚupdateÚprotected_objectsÚRestrictedErrorÚrestricted_objects)r�   ro   r†   r‹   rƒ   rd   Úrelated_nameÚer„   r   r   rt   ®   s$   þ€€ÿzNestedObjects.collectc                    s$   t ƒ  |||¡}|jdd„ |D ƒŽ S )Nc                 S   s   g | ]}|j ‘qS r   )r+   )r   Úrelated_fieldr   r   r   r   Ã   s    z1NestedObjects.related_objects.<locals>.<listcomp>)r}   Úrelated_objectsÚselect_related)r�   Úrelated_modelÚrelated_fieldsro   Úqsr„   r   r   r•   À   s   ÿzNestedObjects.related_objectsc                 C   sj   ||v rg S |  |¡ g }| j |d¡D ]}| |  |||¡¡ q|r)||ƒg}n|g}|r3| |¡ |S )Nr   )ra   r   ÚgetrR   Ú_nestedrS   )r�   rd   Úseenrl   ÚchildrenÚchildÚretr   r   r   r›   Æ   s   

zNestedObjects._nestedc                 C   s6   t ƒ }g }| j dd¡D ]}| |  |||¡¡ q|S )z4
        Return the graph as a nested list.
        Nr   )rq   r   rš   rR   r›   )r�   rl   rœ   ÚrootsÚrootr   r   r   ru   Õ   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   r€   r   r   r   Úcan_fast_deleteß   s   zNestedObjects.can_fast_delete)NNr&   )r   r    r!   r~   rˆ   rt   r•   r›   ru   r¢   Ú__classcell__r   r   r„   r   rs   ¤   s    

rs   c                 C   sF   t | tjtjjfƒr| j}nt | tjjƒr| 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.
    )r_   rm   )rC   r   ÚModelÚbaseÚ	ModelBaser^   ÚqueryÚQuerySetre   r_   rm   )rd   r0   r   r   r   Úmodel_format_dictç   s   
þr©   c                 C   sN   t | tjjƒr|du r|  ¡ }| j} t| ƒ}|d |d }}t|||p%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.
    Nr_   rm   r   )rC   r   r§   r¨   Úcountre   r©   r   )rd   ÚnÚdÚsingularÚpluralr   r   r   Úmodel_ngettextú   s   	r¯   c              	   C   s¢   |j }zt|| ƒ}W n: ttfyD   t| ƒr| }||ƒ}n"t|| ƒr1| dkr1t|| ƒ}||ƒ}nt|| ƒ}t|ƒr>|ƒ }n|}d }Y nw d }t|| ƒ}|||fS )NÚ__str__)r^   Ú_get_non_gfk_fieldr   r   Úcallabler-   rŒ   )r+   rd   Úmodel_adminr0   ÚfÚattrr@   r   r   r   Úlookup_field  s&   



ñ

r¶   c                 C   sR   |   |¡}|jr|jr|jr|jrtƒ ‚|jr'|js't|dƒr'|j|kr't	ƒ ‚|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_relationÚmany_to_oner—   Úone_to_manyr   Úmany_to_manyr-   r·   r   )r0   r+   r4   r   r   r   r±   &  s&   
ÿüüüÿþý
r±   Fc           	      C   s’  d}zt |j| ƒ}z|j}W n ty   |jjj}Y nw W n¢ ty²   | dkr2t|jjƒ}t}n~t| ƒr9| }nCt|| ƒrDt	|| ƒ}n8t|| ƒrOt	|| ƒ}n-|r\| |j
v r\|j
|  }n d| |jjf }|rn|d|jj 7 }|rx|d|jj 7 }t|ƒ‚t|dƒr…|j}n+t|tƒršt|dƒršt|jdƒrš|jj}nt|ƒr¬|jdkr¦d}n
t|jƒ}nt| ƒ}Y n tyÀ   t| ƒ}| }Y nw |rÇ||fS |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±   r^   r_   ÚAttributeErrorr—   r   rD   r²   r-   rŒ   rT   Úobject_namer\   r   r¼   rC   Úpropertyr½   r   r   )	r+   re   r³   Úreturn_attrÚformrµ   r4   ÚlabelÚmessager   r   r   Úlabel_for_fieldC  sh   
þ€

þ
ÿþ
ý

€þrÅ   c              	   C   sB   d}zt |j| ƒ}W n ttfy   Y |S w t|dƒr|j}|S )Nr:   Ú	help_text)r±   r^   r   r   r-   rÆ   )r+   re   rÆ   r4   r   r   r   Úhelp_text_for_field„  s   û
rÇ   c                 C   s"  ddl m} t|dd ƒrt|jƒ | |¡S t|tjƒr|| ƒS | d u r%|S t|tj	ƒr3t
 t | ¡¡S t|tjtjfƒrAt
 | ¡S t|tjƒrNt
 | |j¡S t|tjtjfƒr\t
 | ¡S t|tjƒrk| rktd| j| ƒS t|tjƒrŒ| rŒz
tj| d|jd�W S  ty‹   t| |ƒ Y S w t| |ƒS )Nr   ©Ú_boolean_iconÚflatchoicesz<a href="{}">{}</a>F)Úensure_asciiÚcls)Ú,django.contrib.admin.templatetags.admin_listrÉ   rŒ   ÚdictrÊ   rš   rC   r   ÚBooleanFieldÚDateTimeFieldr   Úlocalizer   Útemplate_localtimeÚ	DateFieldÚ	TimeFieldÚDecimalFieldÚnumber_formatÚdecimal_placesÚIntegerFieldÚ
FloatFieldÚ	FileFieldr   ÚurlÚ	JSONFieldÚjsonÚdumpsÚencoderÚ	TypeErrorÚdisplay_for_value)r@   r4   Úempty_value_displayrÉ   r   r   r   Údisplay_for_field�  s0   

ÿ
rã   c                 C   s´   ddl m} |r|| ƒS | d u r|S t| tƒrt| ƒS t| tjƒr)t t 	| ¡¡S t| tj
tjfƒr7t | ¡S t| ttjtfƒrEt | ¡S t| ttfƒrVd dd„ | D ƒ¡S t| ƒS )Nr   rÈ   z, c                 s   s   � | ]}t |ƒV  qd S r&   )rD   )r   r   r   r   r   r)   ¾  s   € z$display_for_value.<locals>.<genexpr>)rÍ   rÉ   rC   ÚboolrD   Údatetimer   rÑ   r   rÒ   ÚdateÚtimeÚintÚdecimalÚDecimalÚfloatrÖ   rP   rQ   Újoin)r@   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S t‚)Nr$   r%   )r-   r$   r.   re   rî   )r4   r   r   r   Úget_model_from_relationÇ  s   
rï   c              	   C   sª   g }| }|  t¡}|D ]B}|j |¡}t|ƒt|ƒd kr.zt|ƒ W n
 ty-   Y  n!w |jr@|jr7|j	r@| 
¡ }|jj}n|jj}|j}| d|¡ q|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   r^   r,   rn   rï   rî   r¸   Úauto_createdÚconcreteÚrelated_query_nameÚremote_fieldre   r4   r+   r—   Úinsertrì   )re   r(   Úreversed_pathÚparentÚpiecesÚpiecer4   r’   r   r   r   Úreverse_field_pathÎ  s$   
ÿ
rù   c                 C   sD   |  t¡}g }|D ]}|rt|d ƒ}n| }| |j |¡¡ q	|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ï   rS   r^   r,   )re   r(   r÷   rT   rø   rö   r   r   r   Úget_fields_from_pathí  s   
	rú   c                 C   s:  | j }tdƒ� t| |ƒ}W d  ƒ n1 sw   Y  g }|r(| di i¡ n| j r4| dd|ii¡ |r›tdƒ�Y |D ]M}|jD ]}| dt|jjƒt|ƒdœi¡ qB|jD ]\}}	| dt|jjƒt|ƒt|j	d |	ƒdœi¡ qX|j
D ]}
| dt|
jjƒt|
ƒdœi¡ qwq=W d  ƒ |S 1 s–w   Y  |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.
    NÚaddedÚchangedrT   )r+   Úobjectr   )r+   rý   rT   Údeleted)Úchanged_dataÚtranslation_overrideÚ#_get_changed_field_labels_from_formrS   Únew_objectsrD   r^   r_   Úchanged_objectsÚformsÚdeleted_objects)rÂ   Úformsetsra   rÿ   Úchanged_field_labelsÚchange_messageÚformsetÚadded_objectÚchanged_objectÚchanged_fieldsÚdeleted_objectr   r   r   Úconstruct_change_message  sZ   	
ü


þÿÿ

ÿýÿÿ

þÿÿÿê
ÿ à r  c              	   C   sL   g }|D ]}z
| j | jp|}W n ty   |}Y nw | t|ƒ¡ q|S r&   )rT   rÃ   ÚKeyErrorrS   rD   )rÂ   rÿ   r  r3   Úverbose_field_namer   r   r   r  :  s   ÿr  )r7   r&   )NFN)F)=rå   ré   rÝ   Úcollectionsr   Údjango.core.exceptionsr   Ú	django.dbr   r   Údjango.db.models.constantsr   Údjango.db.models.deletionr   Údjango.forms.utilsr   Údjango.urlsr	   r
   Údjango.utilsr   r   Údjango.utils.htmlr   Údjango.utils.regex_helperr   Údjango.utils.textr   Údjango.utils.translationr   r   r   rF   rx   rJ   rì   rM   Ú	Exceptionr   r6   rB   rI   rO   rV   rY   r|   rs   r©   r¯   r¶   r±   rÅ   rÇ   rã   rá   rî   rï   rù   rú   r  r  r   r   r   r   Ú<module>   sT    

;C


A
9