U
    HaC                     @   s  d 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 ddlmZmZ G dd dejZG dd dejZG dd dejZ G dd dej!Z"G dd dej#Z$G dd dej%Z&dd Z'G dd dej(Z)G dd de)Z*G d d! d!ej+Z,G d"d# d#ej-Z.G d$d% d%ej(Z/G d&d' d'ej0Z1G d(d) d)ej2Z3G d*d+ d+ej4Z5G d,d- d-e5Z6G d.d/ d/ej(Z7d0d1 d2D Z8e89d3d4d5 G d6d7 d7Z:G d8d9 d9e:ej;Z<G d:d; d;e:ejZ=dS )<z8
Form Widget classes specific to the Django admin site.
    N)forms)settings)ValidationError)URLValidator)CASCADE)reverse)NoReverseMatch)smart_urlquote)	urlencode)	Truncator)get_languagegettextc                       s<   e Zd ZdZG dd dZd
 fdd	Z fdd	Z  ZS )FilteredSelectMultiplez
    A SelectMultiple with a JavaScript filter interface.

    Note that the resulting JavaScript assumes that the jsi18n
    catalog has been loaded in the page
    c                   @   s   e Zd ZdddgZdS )zFilteredSelectMultiple.Mediazadmin/js/core.jszadmin/js/SelectBox.jszadmin/js/SelectFilter2.jsN__name__
__module____qualname__js r   r   @/tmp/pip-unpacked-wheel-3jxiddxt/django/contrib/admin/widgets.pyMedia   s   r   Nr   c                    s   || _ || _t || d S N)verbose_name
is_stackedsuper__init__)selfr   r   attrschoices	__class__r   r   r   "   s    zFilteredSelectMultiple.__init__c                    sj   t  |||}d|d d d< | jr>|d d d  d7  < | j|d d d< t| j|d d d< |S )NZselectfilterwidgetr   classZstackeddata-field-namezdata-is-stacked)r   get_contextr   r   intr   namevaluer   contextr   r   r   r$   '   s    z"FilteredSelectMultiple.get_context)Nr   )r   r   r   __doc__r   r   r$   __classcell__r   r   r   r   r      s   r   c                       s,   e Zd ZG dd dZd fdd	Z  ZS )AdminDateWidgetc                   @   s   e Zd ZddgZdS )zAdminDateWidget.Mediaadmin/js/calendar.js#admin/js/admin/DateTimeShortcuts.jsNr   r   r   r   r   r   2   s   r   Nc                    s&   ddd|pi }t  j||d d S )NZ
vDateField10r"   sizer   formatr   r   r   r   r3   r   r   r   r   8   s    zAdminDateWidget.__init__)NNr   r   r   r   r   r+   r   r   r   r   r,   1   s   r,   c                       s,   e Zd ZG dd dZd fdd	Z  ZS )AdminTimeWidgetc                   @   s   e Zd ZddgZdS )zAdminTimeWidget.Mediar-   r.   Nr   r   r   r   r   r   >   s   r   Nc                    s&   ddd|pi }t  j||d d S )NZ
vTimeField8r0   r2   r4   r5   r   r   r   r   D   s    zAdminTimeWidget.__init__)NNr6   r   r   r   r   r7   =   s   r7   c                       s.   e Zd ZdZdZdddZ fddZ  ZS )	AdminSplitDateTimezF
    A SplitDateTime Widget that has some admin-specific styling.
    z!admin/widgets/split_datetime.htmlNc                 C   s   t tg}tj| || d S r   )r,   r7   r   ZMultiWidgetr   )r   r   Zwidgetsr   r   r   r   O   s    zAdminSplitDateTime.__init__c                    s,   t  |||}td|d< td|d< |S )NzDate:Z
date_labelzTime:Z
time_label)r   r$   _r&   r   r   r   r$   U   s    zAdminSplitDateTime.get_context)N)r   r   r   r*   template_namer   r$   r+   r   r   r   r   r9   I   s   
r9   c                   @   s   e Zd ZdZdS )AdminRadioSelectzadmin/widgets/radio.htmlNr   r   r   r;   r   r   r   r   r<   \   s   r<   c                   @   s   e Zd ZdZdS )AdminFileWidgetz'admin/widgets/clearable_file_input.htmlNr=   r   r   r   r   r>   `   s   r>   c                 C   s~   i }| rzt | drz|  D ]^\}}t|r0| }t|ttfrTddd |D }nt|trhd| }nt|}|||< q|S )z
    Convert the type of lookups specified in a ForeignKey limit_choices_to
    attribute to a dictionary of query parameters
    items,c                 s   s   | ]}t |V  qd S r   str.0xr   r   r   	<genexpr>o   s     z.url_params_from_lookup_dict.<locals>.<genexpr>)01)	hasattrr?   callable
isinstancetuplelistjoinboolrB   )Zlookupsparamskvr   r   r   url_params_from_lookup_dictd   s    


rS   c                       sJ   e Zd ZdZdZd fdd	Z fddZdd	 Zd
d Zdd Z	  Z
S )ForeignKeyRawIdWidgetzj
    A Widget for displaying ForeignKeys in the "raw_id" interface rather than
    in a <select> box.
    z%admin/widgets/foreign_key_raw_id.htmlNc                    s"   || _ || _|| _t | d S r   )rel
admin_sitedbr   r   )r   rU   rV   r   usingr   r   r   r      s    zForeignKeyRawIdWidget.__init__c                    s   t  |||}| jj}|| jjkrtd|jj|jj	f | jj
d}|  }|r`|dt| 7 }||d< td|d< |d d d	d
 nd |d< |d d r| |\|d< |d< nd |d< |S )Nzadmin:%s_%s_changelist)current_app?related_urlZLookupZ
link_titler!   r   r"   ZvForeignKeyRawIdAdminFieldr(   Z
link_labelZlink_url)r   r$   rU   modelrV   	_registryr   _meta	app_label
model_namer'   url_parametersr
   r:   
setdefaultlabel_and_url_for_value)r   r'   r(   r   r)   Zrel_tor[   rP   r   r   r   r$      s*    z!ForeignKeyRawIdWidget.get_contextc                 C   s   | j j}t|r| }t|S r   )rU   limit_choices_torJ   rS   )r   rd   r   r   r   base_url_parameters   s    z)ForeignKeyRawIdWidget.base_url_parametersc                 C   s.   ddl m} |  }||| j ji |S )Nr   )TO_FIELD_VAR)django.contrib.admin.views.mainrf   re   updaterU   get_related_fieldr'   )r   rf   rP   r   r   r   ra      s    z$ForeignKeyRawIdWidget.url_parametersc              
   C   s   | j  j}z"| j jj| jjf ||i}W n" t| j jj	t
fk
rP   Y dS X z.td| jj|jj|jj f |jfd}W n tk
r   d}Y nX t|d|fS )N rk   z%s:%s_%s_change)argsrk      )rU   ri   r'   r\   Z_default_managerrX   rW   get
ValueErrorZDoesNotExistr   r   rV   r^   r_   Zobject_namelowerpkr   r   words)r   r(   keyobjurlr   r   r   rc      s"    "


z-ForeignKeyRawIdWidget.label_and_url_for_value)NN)r   r   r   r*   r;   r   r$   re   ra   rc   r+   r   r   r   r   rT   x   s   rT   c                       sD   e Zd ZdZdZ fddZdd Zdd Zd	d
 Zdd Z	  Z
S )ManyToManyRawIdWidgetzv
    A Widget for displaying ManyToMany ids in the "raw_id" interface rather than
    in a <select multiple> box.
    z&admin/widgets/many_to_many_raw_id.htmlc                    s4   t  |||}| jj| jjkr0d|d d d< |S )NZvManyToManyRawIdAdminFieldr!   r   r"   )r   r$   rU   r\   rV   r]   r&   r   r   r   r$      s    z!ManyToManyRawIdWidget.get_contextc                 C   s   |   S r   )re   r   r   r   r   ra      s    z$ManyToManyRawIdWidget.url_parametersc                 C   s   dS )Nrj   r   r   r(   r   r   r   rc      s    z-ManyToManyRawIdWidget.label_and_url_for_valuec                 C   s   | |}|r|dS d S )Nr@   )rn   split)r   datafilesr'   r(   r   r   r   value_from_datadict   s    
z)ManyToManyRawIdWidget.value_from_datadictc                 C   s   |rd dd |D S dS )Nr@   c                 s   s   | ]}t |V  qd S r   rA   rD   rR   r   r   r   rF      s     z5ManyToManyRawIdWidget.format_value.<locals>.<genexpr>rk   )rN   rx   r   r   r   format_value   s    z"ManyToManyRawIdWidget.format_value)r   r   r   r*   r;   r$   ra   rc   r|   r~   r+   r   r   r   r   rv      s   rv   c                   @   sf   e Zd ZdZdZdddZdd Zed	d
 Zedd Z	dd Z
dd Zdd Zdd Zdd ZdS )RelatedFieldWidgetWrapperzd
    This class is a wrapper to a given widget to add the add icon for the
    admin interface.
    z)admin/widgets/related_widget_wrapper.htmlNFc           
      C   s   |j | _ |j| _|j| _|| _|| _|d kr8|j|jk}|| _t|dd}| oR|| _	t|dd t
k}	| ot|	 ot|| _| o|| _|| _d S )Nallow_multiple_selectedFZ	on_delete)Zneeds_multipart_formr   r   r!   rU   r\   r]   can_add_relatedgetattrcan_change_relatedr   can_delete_relatedcan_view_relatedrV   )
r   r!   rU   rV   r   r   r   r   multipleZcascader   r   r   r      s    z"RelatedFieldWidgetWrapper.__init__c                 C   s4   t  | }t | j||_| jj|_||t| < |S r   )copydeepcopyr!   r   id)r   memort   r   r   r   __deepcopy__   s
    

z&RelatedFieldWidgetWrapper.__deepcopy__c                 C   s   | j jS r   )r!   	is_hiddenrw   r   r   r   r     s    z#RelatedFieldWidgetWrapper.is_hiddenc                 C   s   | j jS r   )r!   mediarw   r   r   r   r   	  s    zRelatedFieldWidgetWrapper.mediac                 G   s   t d||f  | jj|dS )Nzadmin:%s_%s_%s)rY   rl   )r   rV   r'   )r   infoactionrl   r   r   r   get_related_url  s     z)RelatedFieldWidgetWrapper.get_related_urlc           
   
   C   s   ddl m}m} | jjj}|j|jf}| j| j	_d
dd || j jf|dffD }| j	|||| j|||j| j| j| j| jd	}	| jr| |d|	d	< | jr| |d
d|	d< | js| jr| |dd|	d< |	S )Nr   )IS_POPUP_VARrf   &c                 s   s   | ]}d | V  qdS )z%s=%sNr   )rD   paramr   r   r   rF     s     z8RelatedFieldWidgetWrapper.get_context.<locals>.<genexpr>   )	Zrendered_widgetr   r'   
url_paramsr\   r   r   r   r   addZadd_related_urldeleteZ__fk__Zdelete_related_template_urlZchangeZchange_related_template_url)rg   r   rf   rU   r\   r^   r_   r`   r   r!   rN   ri   r'   renderr   r   r   r   r   r   r   )
r   r'   r(   r   r   rf   Zrel_optsr   r   r)   r   r   r   r$     s2    



z%RelatedFieldWidgetWrapper.get_contextc                 C   s   | j |||S r   )r!   r|   r   rz   r{   r'   r   r   r   r|   -  s    z-RelatedFieldWidgetWrapper.value_from_datadictc                 C   s   | j |||S r   )r!   value_omitted_from_datar   r   r   r   r   0  s    z1RelatedFieldWidgetWrapper.value_omitted_from_datac                 C   s   | j |S r   )r!   id_for_label)r   Zid_r   r   r   r   3  s    z&RelatedFieldWidgetWrapper.id_for_label)NFFF)r   r   r   r*   r;   r   r   propertyr   r   r   r$   r|   r   r   r   r   r   r   r      s"        


r   c                       s   e Zd Zd fdd	Z  ZS )AdminTextareaWidgetNc                    s   t  jddi|pi d d S )Nr"   ZvLargeTextFieldr   r4   r   r   r   r   r   r   8  s    zAdminTextareaWidget.__init__)Nr   r   r   r   r+   r   r   r   r   r   7  s   r   c                       s   e Zd Zd fdd	Z  ZS )AdminTextInputWidgetNc                    s   t  jddi|pi d d S Nr"   Z
vTextFieldr   r4   r   r   r   r   r   =  s    zAdminTextInputWidget.__init__)Nr   r   r   r   r   r   <  s   r   c                       s   e Zd Zd fdd	Z  ZS )AdminEmailInputWidgetNc                    s   t  jddi|pi d d S r   r4   r   r   r   r   r   B  s    zAdminEmailInputWidget.__init__)Nr   r   r   r   r   r   A  s   r   c                       s2   e Zd ZdZdef fdd	Z fddZ  ZS )AdminURLFieldWidgetzadmin/widgets/url.htmlNc                    s&   t  jddi|pi d | | _d S )Nr"   Z	vURLFieldr   )r   r   	validator)r   r   Zvalidator_classr   r   r   r   I  s    zAdminURLFieldWidget.__init__c                    s   z|  |r|nd d}W n tk
r2   d}Y nX t |||}td|d< td|d< |rpt|d d	 nd|d d
< ||d< |S )Nrk   TFz
Currently:Zcurrent_labelzChange:Zchange_labelr!   r(   href	url_valid)r   r   r   r$   r:   r	   )r   r'   r(   r   r   r)   r   r   r   r$   M  s    
 zAdminURLFieldWidget.get_context)r   r   r   r;   r   r   r$   r+   r   r   r   r   r   F  s   r   c                       s"   e Zd ZdZd fdd	Z  ZS )AdminIntegerFieldWidgetZvIntegerFieldNc                    s    t  jd| ji|pi d d S )Nr"   r   )r   r   
class_namer   r   r   r   r   ^  s    z AdminIntegerFieldWidget.__init__)N)r   r   r   r   r   r+   r   r   r   r   r   [  s   r   c                   @   s   e Zd ZdZdS )AdminBigIntegerFieldWidgetZvBigIntegerFieldN)r   r   r   r   r   r   r   r   r   b  s   r   c                       s   e Zd Zd fdd	Z  ZS )AdminUUIDInputWidgetNc                    s   t  jddi|pi d d S )Nr"   Z
vUUIDFieldr   r4   r   r   r   r   r   g  s    zAdminUUIDInputWidget.__init__)Nr   r   r   r   r   r   f  s   r   c                 C   s   i | ]}|  |qS r   )rp   rC   r   r   r   
<dictcomp>n  s      r   )-arazbgcacsdadeeleneseteufafifrglhehihrhur   isitjakmkoltlvmkmsnbnlplzpt-BRptroruskzsr-Cyrlsrsvthtrukvizzh-CNzzh-TW)zzh-hanszzh-hantc                       sN   e Zd ZdZdZdddZdd Zd fd	d
	ZdddZe	dd Z
  ZS )AutocompleteMixinz
    Select widget mixin that loads options from AutocompleteJsonView via AJAX.

    Renders the necessary data attributes for select2 and adds the static form
    media.
    z%s:autocompleteNr   c                 C   s2   || _ || _|| _|| _|d kr$i n| | _d S r   )fieldrV   rW   r   r   r   )r   r   rV   r   r   rX   r   r   r   r     s
    zAutocompleteMixin.__init__c                 C   s   t | j| jj S r   )r   url_namerV   r'   rw   r   r   r   get_url  s    zAutocompleteMixin.get_urlc                    s|   t  j||d}|dd |ddd|  | jjjj| jjjj	| jj
dt| j d|d |d rhdnd d d	 |S )
z
        Set select2's AJAX attributes.

        Attributes can be set using the html5 data attribute.
        Nested attributes require a double dash as per
        https://select2.org/configuration/data-attributes#nested-subkey-options
        )extra_attrsr"   rk   true   GETzadmin-autocomplete )zdata-ajax--cachezdata-ajax--delayzdata-ajax--typezdata-ajax--urlzdata-app-labelzdata-model-namer#   z
data-themezdata-allow-clearzdata-placeholderr"   )r   build_attrsrb   rh   r   r   r\   r^   r_   r`   r'   jsondumpsis_required)r   Z
base_attrsr   r   r   r   r   r     s     

zAutocompleteMixin.build_attrsc              
      s
  dg df}|g}d} fdd|D } j sN jsN|d  |dddd  jjjj}t jjd|j	j
|j
 fd	d
 jj jjf d |iD }	|	D ]V\}
}t|
|ko|dkpΈ j}||O }t|d }|d }| ||
||| q|S )z9Return selected options based on the ModelChoiceIterator.Nr   Fc                    s&   h | ]}t | jjjkrt |qS r   )rB   r   r   Zempty_valuesr}   rw   r   r   	<setcomp>  s   z.AutocompleteMixin.optgroups.<locals>.<setcomp>r   rk   
field_namec                 3   s&   | ]}t | jj|fV  qd S r   )r   r   r   Zlabel_from_instance)rD   rt   r   Zto_field_namer   r   rF     s   z.AutocompleteMixin.optgroups.<locals>.<genexpr>z%s__in)r   r   appendZcreate_optionr   Zremote_fieldr\   r^   r   rq   Zattname	get_fieldr   ZquerysetrX   rW   filterrB   len)r   r'   r(   attrdefaultgroupsZhas_selectedZselected_choicesZremote_model_optsr   Zoption_valueZoption_labelselectedindexZsubgroupr   r   r   	optgroups  s.    

zAutocompleteMixin.optgroupsc                 C   sZ   t jr
dnd}tt }|r(d| fnd}tjd| d| f| d dd	| d
fidS )Nrk   z.minz"admin/js/vendor/select2/i18n/%s.jsr   z"admin/js/vendor/jquery/jquery%s.jsz)admin/js/vendor/select2/select2.full%s.js)zadmin/js/jquery.init.jszadmin/js/autocomplete.jsZscreenz&admin/css/vendor/select2/select2%s.csszadmin/css/autocomplete.css)r   css)r   DEBUGSELECT2_TRANSLATIONSrn   r   r   r   )r   extraZ	i18n_nameZ	i18n_filer   r   r   r     s"    zAutocompleteMixin.media)Nr   N)N)N)r   r   r   r*   r   r   r   r   r   r   r   r+   r   r   r   r   r   x  s   

r   c                   @   s   e Zd ZdS )AutocompleteSelectNr   r   r   r   r   r   r   r     s   r   c                   @   s   e Zd ZdS )AutocompleteSelectMultipleNr   r   r   r   r   r     s   r   )>r*   r   r   Zdjangor   Zdjango.confr   Zdjango.core.exceptionsr   Zdjango.core.validatorsr   Zdjango.db.modelsr   Zdjango.urlsr   Zdjango.urls.exceptionsr   Zdjango.utils.htmlr	   Zdjango.utils.httpr
   Zdjango.utils.textr   Zdjango.utils.translationr   r   r:   ZSelectMultipler   Z	DateInputr,   Z	TimeInputr7   ZSplitDateTimeWidgetr9   ZRadioSelectr<   ZClearableFileInputr>   rS   Z	TextInputrT   rv   ZWidgetr   ZTextarear   r   Z
EmailInputr   ZURLInputr   ZNumberInputr   r   r   r   rh   r   ZSelectr   r   r   r   r   r   <module>   sF   KW_