o
    uvXj_G  ã                   @   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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&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.dBd)d*„Z/dBd+d,„Z0d-d.„ Z1dCd0d1„Z2d2d3„ Z3d4d5„ Z4dDd6d7„Z5G d8d9„ d9e$ƒZ6d:d;„ Z7d<d=„ Z8d>d?„ Z9d@dA„ Z:dS )Eé    N)Údefaultdict)ÚFieldDoesNotExist)ÚmodelsÚrouter)Ú
LOOKUP_SEP)Ú	Collector)Úpretty_name)ÚNoReverseMatchÚreverse)ÚformatsÚtimezone)Úformat_html)Úcapfirst)ÚngettextÚoverridec                 C   s   i | ]}|d | “qS )z_%02X© )Ú.0Úir   r   úW/var/www/html/myproject/venv/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 ]5}|dkr| jj}z|  |¡}W n	 ty!   Y qw t|dƒr<| ¡ }|d j} t	dd„ |D ƒƒr< dS qdS )zT
    Return True if 'distinct()' should be used to query the given lookup path.
    ÚpkÚget_path_infoéÿÿÿÿc                 s   s   � | ]}|j V  qd S ©N)Úm2m)r   Úpathr   r   r   Ú	<genexpr>.   s   € z(lookup_needs_distinct.<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_needs_distinct   s    
þ

€r5   c                 C   s2   |   d¡r| d¡}|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Úvaluer   r   r   Úprepare_lookup_value4   s   


þr@   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   ÚquoteA   s   rG   c                 C   s   t  dd„ | ¡S )zUndo the effects of quote().c                 S   s   t |  d¡ S )Nr   )ÚUNQUOTE_MAPÚgroup)Úmr   r   r   Ú<lambda>M   s    zunquote.<locals>.<lambda>)Ú
UNQUOTE_REÚsubrE   r   r   r   ÚunquoteK   s   rN   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.
    )rA   ÚlistÚtupleÚextendÚappend)ÚfieldsÚflatr3   r   r   r   ÚflattenP   s   rU   c                 C   s(   g }| D ]\}}|  t|d ƒ¡ q|S )z?Return a list of field names from an admin fieldsets structure.rS   )rQ   rU   )Ú	fieldsetsÚfield_namesr*   r/   r   r   r   Úflatten_fieldsets]   s   
ÿrX   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   )Úusingc                    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_namerG   r"   r	   r   )ÚobjÚmodelÚ	has_adminr/   Úno_edit_linkÚ	admin_url)Ú
admin_siteÚperms_neededÚrequestr   r   Úformat_callbacky   s2   
þÿüþýz,get_deleted_objects.<locals>.format_callbackc                    s   g | ]}ˆ |ƒ‘qS r   r   )r   rb   )rj   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   rc   Úobjsr   r   r   r   š   s    z'get_deleted_objects.<locals>.<dictcomp>)Ú
IndexErrorÚsetr   Údb_for_writer\   rc   ÚNestedObjectsÚcollectÚnestedÚ	protectedÚ
model_objsÚitems)	rm   ri   rg   rb   rY   Ú	collectorÚ	to_deletert   Úmodel_countr   )rg   rj   rh   ri   r   Úget_deleted_objectsg   s   ÿ


rz   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 )rq   c                    s.   t ƒ j|i |¤Ž i | _tƒ | _ttƒ| _d S r%   )ÚsuperÚ__init__Úedgesro   rt   r   ru   ©ÚselfÚargsÚkwargs©rZ   r   r   r|       s   zNestedObjects.__init__c                 C   s   | j  |g ¡ |¡ d S r%   )r}   Ú
setdefaultrR   )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w )Nú+)Úclassr`   Úsource_attr)r<   r\   ra   r`   r†   Úgetattrru   rc   r_   r{   rr   r   ÚProtectedErrorrt   ÚupdateÚprotected_objects)r   rm   r„   r‰   r�   rb   Úrelated_nameÚer‚   r   r   rr   ©   s   þ€ÿzNestedObjects.collectc                    s   t ƒ  ||¡}| |jj¡S r%   )r{   Úrelated_objectsÚselect_relatedr3   r*   )r   Úrelatedrm   Ú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   )r_   r}   ÚgetrQ   Ú_nestedrR   )r   rb   Úseenrj   Ú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   )ro   r}   r”   rQ   r•   )r   rj   r–   ÚrootsÚrootr   r   r   rs   Ì   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†   rr   r�   r•   rs   rœ   Ú__classcell__r   r   r‚   r   rq   Ÿ   s    

rq   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]   rk   )rA   r   ÚModelÚbaseÚ	ModelBaser\   ÚqueryÚQuerySetrc   r]   rk   )rb   r/   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]   rk   r   )rA   r   r¡   r¢   Úcountrc   r£   r   )rb   Ú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*   rb   Úmodel_adminr/   Ú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_oneÚrelated_modelÚone_to_manyr   Úmany_to_manyr,   r±   r   )r/   r*   r3   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| }nDt|| ƒrDt	|| ƒ}n9t|| ƒrOt	|| ƒ}n.|r\| |j
v r\|j
|  }n!d| |jjf }|ro|d|jjf 7 }|ry|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   rB   r¬   r,   rŠ   rS   Úobject_namerZ   r   r·   rA   Úpropertyr¸   r   r   )	r*   rc   r­   Úreturn_attrÚformr¯   r3   ÚlabelÚmessager   r   r   Úlabel_for_field2  s`   
þ€



ÿ
þ

€þrÀ   c              	   C   sB   d}zt |j| ƒ}W n ttfy   Y |S w t|dƒr|j}|S )Nr9   Ú	help_text)r«   r\   r   r   r,   rÁ   )r*   rc   rÁ   r3   r   r   r   Úhelp_text_for_fieldn  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| |ƒS )Nr   ©Ú_boolean_iconÚflatchoicesz<a href="{}">{}</a>)Ú,django.contrib.admin.templatetags.admin_listrÄ   rŠ   ÚdictrÅ   r”   rA   r   ÚBooleanFieldÚDateTimeFieldr   Úlocalizer   Útemplate_localtimeÚ	DateFieldÚ	TimeFieldÚDecimalFieldÚnumber_formatÚdecimal_placesÚIntegerFieldÚ
FloatFieldÚ	FileFieldr   ÚurlÚdisplay_for_value)r?   r3   Úempty_value_displayrÄ   r   r   r   Údisplay_for_fieldz  s$   


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%   )rB   )r   r   r   r   r   r(   £  s   € z$display_for_value.<locals>.<genexpr>)rÆ   rÄ   rA   ÚboolrB   Údatetimer   rÊ   r   rË   ÚdateÚtimeÚintÚdecimalÚDecimalÚfloatrÏ   rO   rP   Ú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|  ¡ d jjS t‚)Nr#   r$   )r,   r#   r-   rc   râ   )r3   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+   rl   rã   râ   r²   Úauto_createdÚconcreteÚrelated_query_nameÚremote_fieldrc   r3   r*   r´   Úinsertrà   )rc   r'   Úreversed_pathÚparentÚpiecesÚpiecer3   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ã   rR   r\   r+   )rc   r'   rë   rS   rì   rê   r   r   r   Úget_fields_from_pathÒ  s   
	rî   c           	   
   C   sø   g }|r|  di i¡ n| jr|  dd| jii¡ |rztdƒ�S |D ]G}|jD ]}|  dt|jjƒt|ƒdœi¡ q'|jD ]\}}|  dt|jjƒt|ƒ|dœi¡ q=|jD ]}|  dt|jjƒt|ƒdœi¡ qVq"W d  ƒ |S 1 suw   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.
    ÚaddedÚchangedrS   N)r*   Úobject)r*   rñ   rS   Údeleted)	rR   Úchanged_dataÚtranslation_overrideÚnew_objectsrB   r\   r]   Úchanged_objectsÚdeleted_objects)	r½   Úformsetsr_   Úchange_messageÚformsetÚadded_objectÚchanged_objectÚchanged_fieldsÚdeleted_objectr   r   r   Úconstruct_change_messageæ  sH   


þÿ
ýÿ

þÿÿð
ÿèrÿ   r%   )NFN)F);rÙ   rÝ   ÚreÚ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.textr   Údjango.utils.translationr   r   rô   rD   rv   rH   Úcompilerà   rL   Ú	Exceptionr   r5   r@   rG   rN   rU   rX   rz   rq   r£   r©   r°   r«   rÀ   rÂ   r×   rÕ   râ   rã   rí   rî   rÿ   r   r   r   r   Ú<module>   sN    

8?


<
