o
    z,hU                     @   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 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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/dd  Z0dOd"d#Z1d$d% Z2d&d' Z3d(d) Z4d*d+ Z5d,d- Z6d.d/ Z7G d0d1 d1eZ8d2d3 Z9dPd4d5Z:dPd6d7Z;d8d9 Z<dQd;d<Z=d=d> Z>dRd?d@Z?dRdAdBZ@G dCdD dDe-ZAdEdF ZBdGdH ZCdIdJ ZDdKdL ZEdMdN ZFdS )S    N)defaultdict)reduce)or_)FieldDoesNotExist)EMPTY_VALUES)modelsrouter)
LOOKUP_SEP)	Collector)pretty_name)NoReverseMatchreverse)formatstimezone)make_hashable)format_html)_lazy_re_compile)capfirst)ngettext)overridec                 C   s   i | ]}|d | qS )z_%02X ).0ir   r   P/var/www/html/rh/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          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_infosc                 s   s    | ]}|j V  qd S N)m2m)r   pathr   r   r   	<genexpr>5   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    


r;   c                 C   s    |  |}t|tr|d S |S )Nr*   )get
isinstancelist)
parameterskeyvaluer   r   r   get_last_value_from_parameters<   s   
rB   ,c                    sP   t |tr fdd|D S  dr|}|S  dr&| dv}|S )zJ
    Return a lookup value prepared to be used in queryset filtering.
    c                    s   g | ]	}t  |d qS ))	separator)prepare_lookup_valuer   r   r@   rD   r   r   r"   F   r   z(prepare_lookup_value.<locals>.<listcomp>__in__isnull) false0)r=   r>   endswithr/   lower)r@   rA   rD   r   rG   r   rE   A   s   



rE   c                    s:   t  }|  D ]\ }|tt fdd|D M }q|S )Nc                 3   s    | ]
}t  |fV  qd S r+   )r   Q)r   itemparamr   r   r.   S   s    z8build_q_object_from_lookup_parameters.<locals>.<genexpr>)r   rO   itemsr   r   )r?   q_objectparam_item_listr   rQ   r   %build_q_object_from_lookup_parametersP   s   rV   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.
    )r=   str	translate	QUOTE_MAPsr   r   r   quoteW   s   r\   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>c   s    zunquote.<locals>.<lambda>)
UNQUOTE_REsubrZ   r   r   r   unquotea   s   rb   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.
    )r=   r>   tupleextendappend)fieldsflatr9   r   r   r   flattenf   s   rh   c                 C   s(   g }| D ]\}}| t|d  q|S )z?Return a list of field names from an admin fieldsets structure.rf   )rd   rh   )	fieldsetsfield_namesr0   r5   r   r   r   flatten_fieldsetss   s   rk   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}dt|j| f } |rM || s#|j ztd j	|j
|jf d t| jf}W n tyB   | Y S w tdt|j|| S |S )Nz%s: %sz%s:%s_%s_changez{}: <a href="{}">{}</a>)	__class___metar   verbose_nameis_registeredget_model_adminhas_delete_permissionaddr   r0   	app_label
model_namer\   r(   r   r   )objmodelr5   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   rw   )r~   r   r   r"      s    z'get_deleted_objects.<locals>.<listcomp>c                 S   s   i | ]\}}|j jt|qS r   )ro   verbose_name_plurallen)r   rx   objsr   r   r   r      s    z'get_deleted_objects.<locals>.<dictcomp>)
IndexErrorsetr   db_for_writero   rx   NestedObjectscollectnested	protected
model_objsrS   )	r   r}   r{   rw   rl   	collector	to_deleter   model_countr   )r{   r~   r|   r}   r   get_deleted_objects{   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 )r   c                    s.   t  j|i | i | _t | _tt| _d S r+   )super__init__edgesr   r   r   r   selfargskwargsrn   r   r   r      s   zNestedObjects.__init__c                 C   s   | j |g | d S r+   )r   
setdefaultre   )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+)classru   source_attr)rM   ro   rv   ru   r   getattrr   rx   rt   r   r   r   ProtectedErrorr   updateprotected_objectsRestrictedErrorrestricted_objects)r   r   r   r   r   rw   related_nameer   r   r   r      s$   zNestedObjects.collectc                    s$   t  |||}|jdd |D  S )Nc                 S   s   g | ]}|j qS r   )r0   )r   related_fieldr   r   r   r"      s    z1NestedObjects.related_objects.<locals>.<listcomp>)r   related_objectsselect_related)r   related_modelrelated_fieldsr   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   )rt   r   r<   rd   _nestedre   )r   rw   seenr~   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   )r   r   r<   rd   r   )r   r~   r   rootsrootr   r   r   r      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   r   r   r   r   r   __classcell__r   r   r   r   r      s    

r   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.
    )rp   r   )r=   r   Modelbase	ModelBasero   queryQuerySetrx   rp   r   )rw   r5   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.
    Nrp   r   r   )r=   r   r   r   countrx   r   r   )rw   ndsingularpluralr   r   r   model_ngettext  s   	r   c           	   	   C   s  |j }zt|| }W nk ttfyu   t| r| }||}nSt|| r1| dkr1t|| }||}n@t }t|| |}t|rB| }n||u r^|}| t	D ]}t|||}||u r] Y dS qM|}t|drqt|j
| rqt|j
| }d }Y nw d }t|| }|||fS )N__str__)NNNrx   )ro   _get_non_gfk_fieldr   r#   callabler2   r   objectr/   r	   rx   )	r0   rw   model_adminr5   fattrrA   sentinelpartr   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)
r1   is_relationmany_to_oner   one_to_manyr   many_to_manyr2   r   r#   )r5   r0   r9   r   r   r   r   B  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}nt| r9| }nZt|| rDt	|| }nOt|| rOt	|| }nD|r\| |j
v r\|j
|  }n7z	t|| d }W n- ttfy   d|  d|jj }|r|d|jj 7 }|r|d|jj 7 }t|w t|dr|j}n+t|trt|drt|jdr|jj}nt|r|jd	krd
}n
t|j}nt| }Y n ty   t| }| }Y nw |r||fS |S )a  
    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, including across related
    objects. 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   r*   zUnable to lookup 'z' on z or short_descriptionfgetz<lambda>z--)r   ro   rp   AttributeErrorr   r   rW   r   r2   r   rf   get_fields_from_pathNotRelationFieldobject_namern   r$   r   r=   propertyr   r   r#   )	r0   rx   r   return_attrformr   r9   labelmessager   r   r   label_for_field_  sj   	






r   c              	   C   sB   d}zt |j| }W n ttfy   Y |S w t|dr|j}|S )NrJ   	help_text)r   ro   r   r#   r2   r   )r0   rx   r   r9   r   r   r   help_text_for_field  s   
r   c                 C   s  ddl m} t|dd r1z
t|j| |W S  ty0   t|j}t| } t|| | Y S w t|t	j
r;|| S | |jv rB|S t|t	jrPtt| S t|t	jt	jfr^t| S t|t	jrkt| |jS t|t	jt	jfryt| S t|t	jr| r|std| j| S t|t	jr| r|std| | S t|t	jr| rz
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<   	TypeErrorr   r=   r   BooleanFieldempty_valuesDateTimeFieldr   localizer   template_localtime	DateField	TimeFieldDecimalFieldnumber_formatdecimal_placesIntegerField
FloatField	FileFieldr   urlURLField	JSONFieldjsondumpsencoderdisplay_for_value)rA   r9   empty_value_display
avoid_linkr   r   r   r   r   display_for_field  s@   




r   c                 C   s   ddl m} |r|| S | tv 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+   )rW   rF   r   r   r   r.     s    z$display_for_value.<locals>.<genexpr>)r   r   r   r=   boolrW   datetimer   r   r   r   datetimeintdecimalDecimalfloatr   r>   rc   join)rA   r   booleanr   r   r   r   r     s    


r   c                   @   s   e Zd ZdS )r   N)r$   r%   r&   r   r   r   r   r     s    r   c                 C   s   t | dr| jd jjS t)Nr)   r*   )r2   r)   r3   rx   r   )r9   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 )zCreate 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	   ro   r1   r   r  r   r   auto_createdconcreterelated_query_nameremote_fieldrx   r9   r0   r   insertr  )rx   r-   reversed_pathparentpiecespiecer9   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  re   ro   r1   )rx   r-   r  rf   r  r  r   r   r   r     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 |rt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 sw   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changedrf   )r0   r   r   )r0   r   rf   deleted)changed_datatranslation_override#_get_changed_field_labels_from_formre   new_objectsrW   ro   rp   changed_objectsformsdeleted_objects)r   formsetsrt   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+   )rf   r   KeyErrorre   rW   )r   r  r  r8   verbose_field_namer   r   r   r  `  s   r  )rC   r+   )NFN)F)Gr   r  r   collectionsr   	functoolsr   operatorr   django.core.exceptionsr   django.core.validatorsr   	django.dbr   r   django.db.models.constantsr	   django.db.models.deletionr
   django.forms.utilsr   django.urlsr   r   django.utilsr   r   django.utils.hashabler   django.utils.htmlr   django.utils.regex_helperr   django.utils.textr   django.utils.translationr   r   r  rY   rS   r]   r  r`   	Exceptionr#   r;   rB   rE   rV   r\   rb   rh   rk   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r#  r  r   r   r   r   <module>   s`    

<C

#
B

'9