3
u^lC              .   @   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 dhD Z8e8j9d_d`da G dbdc dcZ:G ddde dee:ej;Z<G dfdg dge:ejZ=dS )iz8
Form Widget classes specific to the Django admin site.
    N)forms)settings)ValidationError)URLValidator)CASCADE)reverse)NoReverseMatch)smart_urlquote)	mark_safe)	Truncator)get_languagegettextc                   s>   e Zd ZdZedd Zdf f 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             C   s6   t jr
dnd}d| ddddg}tjdd	 |D d
S )N z.minzvendor/jquery/jquery%s.jszjquery.init.jszcore.jszSelectBox.jszSelectFilter2.jsc             S   s   g | ]}d | qS )zadmin/js/%s ).0pathr   r   @/usr/lib/python3.6/site-packages/django/contrib/admin/widgets.py
<listcomp>%   s    z0FilteredSelectMultiple.media.<locals>.<listcomp>)js)r   DEBUGr   Media)selfextrar   r   r   r   media   s    zFilteredSelectMultiple.mediaNc                s   || _ || _t j|| d S )N)verbose_name
is_stackedsuper__init__)r   r   r   attrschoices)	__class__r   r   r   '   s    zFilteredSelectMultiple.__init__c                sj   t  j|||}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stackedzdata-field-namezdata-is-stacked)r   get_contextr   r   int)r   namevaluer   context)r!   r   r   r$   ,   s    z"FilteredSelectMultiple.get_context)	__name__
__module____qualname____doc__propertyr   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.Mediazadmin/js/calendar.jsz#admin/js/admin/DateTimeShortcuts.jsN)r)   r*   r+   r   r   r   r   r   r   7   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   r2   )r!   r   r   r   =   s    zAdminDateWidget.__init__)NN)r)   r*   r+   r   r   r.   r   r   )r!   r   r/   6   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.Mediazadmin/js/calendar.jsz#admin/js/admin/DateTimeShortcuts.jsN)r)   r*   r+   r   r   r   r   r   r   C   s   r   Nc                s&   ddd|pi }t  j||d d S )NZ
vTimeField8)r#   r1   )r   r2   )r   r   )r   r   r2   )r!   r   r   r   I   s    zAdminTimeWidget.__init__)NN)r)   r*   r+   r   r   r.   r   r   )r!   r   r3   B   s   r3   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j| || d S )N)r/   r3   r   MultiWidgetr   )r   r   widgetsr   r   r   r   T   s    zAdminSplitDateTime.__init__c                s,   t  j|||}td|d< td|d< |S )NzDate:Z
date_labelzTime:Z
time_label)r   r$   _)r   r&   r'   r   r(   )r!   r   r   r$   Z   s    zAdminSplitDateTime.get_context)N)r)   r*   r+   r,   template_namer   r$   r.   r   r   )r!   r   r5   N   s   
r5   c               @   s   e Zd ZdZdS )AdminRadioSelectzadmin/widgets/radio.htmlN)r)   r*   r+   r9   r   r   r   r   r:   a   s   r:   c               @   s   e Zd ZdZdS )AdminFileWidgetz'admin/widgets/clearable_file_input.htmlN)r)   r*   r+   r9   r   r   r   r   r;   e   s   r;   c             C   s   i }| r~t | dr~xj| j D ]^\}}t|r2| }t|ttfrVdjdd |D }nt|trjd| }nt|}|||< qW |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 )N)str)r   xr   r   r   	<genexpr>t   s    z.url_params_from_lookup_dict.<locals>.<genexpr>01)rA   rB   )	hasattrr<   callable
isinstancetuplelistjoinboolr>   )lookupsparamskvr   r   r   url_params_from_lookup_dicti   s    

rN   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 j| d S )N)rel
admin_sitedbr   r   )r   rP   rQ   r   using)r!   r   r   r      s    zForeignKeyRawIdWidget.__init__c                s   t  j|||}| jj}|| jjkrtd|jj|jj	f | jj
d}| j }|rp|ddjdd |j D  7 }t||d< td|d	< |d
 d jdd nd |d< |d
 d r| j|\|d< |d< nd |d< |S )Nzadmin:%s_%s_changelist)current_app?z&amp;c             s   s   | ]\}}d ||f V  qdS )z%s=%sNr   )r   rL   rM   r   r   r   r@      s    z4ForeignKeyRawIdWidget.get_context.<locals>.<genexpr>related_urlLookupZ
link_titler"   r   r#   ZvForeignKeyRawIdAdminFieldr'   Z
link_labelZlink_url)r   r$   rP   modelrQ   	_registryr   _meta	app_label
model_namer&   url_parametersrH   r<   r
   r8   
setdefaultlabel_and_url_for_value)r   r&   r'   r   r(   Zrel_torV   rK   )r!   r   r   r$      s&    
 z!ForeignKeyRawIdWidget.get_contextc             C   s   | j j}t|r| }t|S )N)rP   limit_choices_torD   rN   )r   r`   r   r   r   base_url_parameters   s    z)ForeignKeyRawIdWidget.base_url_parametersc             C   s.   ddl m} | j }|j|| jj ji |S )Nr   )TO_FIELD_VAR)django.contrib.admin.views.mainrb   ra   updaterP   get_related_fieldr&   )r   rb   rK   r   r   r   r]      s    z$ForeignKeyRawIdWidget.url_parametersc             C   s   | j j j}y"| j jjj| jjf ||i}W n  t| j jj	t
fk
rN   dS X y.td| jj|jj|jjj f |jfd}W n tk
r   d}Y nX t|jd|fS )Nr   z%s:%s_%s_change)args   )r   r   )rP   re   r&   rX   _default_managerrS   rR   get
ValueErrorDoesNotExistr   r   rQ   rZ   r[   object_namelowerpkr   r   words)r   r'   keyobjurlr   r   r   r_      s    "
z-ForeignKeyRawIdWidget.label_and_url_for_value)NN)r)   r*   r+   r,   r9   r   r$   ra   r]   r_   r.   r   r   )r!   r   rO   }   s   rO   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jkr0d|d d d< |S )NZvManyToManyRawIdAdminFieldr"   r   r#   )r   r$   rP   rX   rQ   rY   )r   r&   r'   r   r(   )r!   r   r   r$      s    z!ManyToManyRawIdWidget.get_contextc             C   s   | j  S )N)ra   )r   r   r   r   r]      s    z$ManyToManyRawIdWidget.url_parametersc             C   s   dS )Nr   )r   r   r   )r   r'   r   r   r   r_      s    z-ManyToManyRawIdWidget.label_and_url_for_valuec             C   s   |j |}|r|jdS d S )Nr=   )ri   split)r   datafilesr&   r'   r   r   r   value_from_datadict   s    
z)ManyToManyRawIdWidget.value_from_datadictc             C   s   |rdj dd |D S dS )Nr=   c             s   s   | ]}t |V  qd S )N)r>   )r   rM   r   r   r   r@      s    z5ManyToManyRawIdWidget.format_value.<locals>.<genexpr>r   )rH   )r   r'   r   r   r   format_value   s    z"ManyToManyRawIdWidget.format_value)r)   r*   r+   r,   r9   r$   r]   r_   rw   rx   r.   r   r   )r!   r   rs      s   rs   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_selectedF	on_delete)needs_multipart_formr   r    r"   rP   rX   rY   can_add_relatedgetattrcan_change_relatedr   can_delete_relatedcan_view_relatedrQ   )
r   r"   rP   rQ   r}   r   r   r   multipleZcascader   r   r   r      s    z"RelatedFieldWidgetWrapper.__init__c             C   s4   t j | }t j| j||_| jj|_||t| < |S )N)copydeepcopyr"   r   id)r   memorq   r   r   r   __deepcopy__  s
    

z&RelatedFieldWidgetWrapper.__deepcopy__c             C   s   | j jS )N)r"   	is_hidden)r   r   r   r   r   
  s    z#RelatedFieldWidgetWrapper.is_hiddenc             C   s   | j jS )N)r"   r   )r   r   r   r   r     s    zRelatedFieldWidgetWrapper.mediac             G   s   t d||f  | jj|dS )Nzadmin:%s_%s_%s)rT   rf   )r   rQ   r&   )r   infoactionrf   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j
dd || jj jf|dfgD }| j	j|||| j|||j| j| j| j| jd	}	| jr| j|d|	d	< | jr| j|d
d|	d< | js| jr| j|dd|	d< |	S )Nr   )IS_POPUP_VARrb   &c             s   s   | ]}d | V  qdS )z%s=%sNr   )r   paramr   r   r   r@     s    z8RelatedFieldWidgetWrapper.get_context.<locals>.<genexpr>   )	Zrendered_widgetr   r&   
url_paramsrX   r}   r   r   r   addZadd_related_urldeleteZ__fk__Zdelete_related_template_urlchangeZchange_related_template_url)rc   r   rb   rP   rX   rZ   r[   r\   r    r"   rH   re   r&   renderr   r   r}   r   r   r   r   )
r   r&   r'   r   r   rb   rel_optsr   r   r(   r   r   r   r$     s.    



z%RelatedFieldWidgetWrapper.get_contextc             C   s   | j j|||S )N)r"   rw   )r   ru   rv   r&   r   r   r   rw   2  s    z-RelatedFieldWidgetWrapper.value_from_datadictc             C   s   | j j|||S )N)r"   value_omitted_from_data)r   ru   rv   r&   r   r   r   r   5  s    z1RelatedFieldWidgetWrapper.value_omitted_from_datac             C   s   | j j|S )N)r"   id_for_label)r   id_r   r   r   r   8  s    z&RelatedFieldWidgetWrapper.id_for_label)NFFF)r)   r*   r+   r,   r9   r   r   r-   r   r   r   r$   rw   r   r   r   r   r   r   ry      s     
ry   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   )r   r   )r   r   )r!   r   r   r   =  s    zAdminTextareaWidget.__init__)N)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 )AdminTextInputWidgetNc                s   t  jddi|pi d d S )Nr#   
vTextField)r   )r   r   )r   r   )r!   r   r   r   B  s    zAdminTextInputWidget.__init__)N)r)   r*   r+   r   r.   r   r   )r!   r   r   A  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 )Nr#   r   )r   )r   r   )r   r   )r!   r   r   r   G  s    zAdminEmailInputWidget.__init__)N)r)   r*   r+   r   r.   r   r   )r!   r   r   F  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	vURLField)r   )r   r   	validator)r   r   Zvalidator_class)r!   r   r   r   N  s    zAdminURLFieldWidget.__init__c                s   y| j |r|nd d}W n tk
r2   d}Y nX t j|||}td|d< td|d< |rpt|d d	 nd|d d
< ||d< |S )Nr   TFz
Currently:Zcurrent_labelzChange:Zchange_labelr"   r'   Zhref	url_valid)r   r   r   r$   r8   r	   )r   r&   r'   r   r   r(   )r!   r   r   r$   R  s    
 zAdminURLFieldWidget.get_context)r)   r*   r+   r9   r   r   r$   r.   r   r   )r!   r   r   K  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_name)r   r   )r!   r   r   r   c  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   g  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
vUUIDField)r   )r   r   )r   r   )r!   r   r   r   l  s    zAdminUUIDInputWidget.__init__)N)r)   r*   r+   r   r.   r   r   )r!   r   r   k  s   r   c             C   s   i | ]}||j  qS r   )rm   )r   r?   r   r   r   
<dictcomp>s  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plpt-BRptrorusksr-Cyrlsrsvthtrukvizzh-CNzzh-TW)zzh-hanszzh-hantc                   sT   e Zd ZdZdZdf df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:%s_%s_autocompleteNc             C   s2   || _ || _|| _|| _|d kr$i n|j | _d S )N)rP   rQ   rR   r    r   r   )r   rP   rQ   r   r    rS   r   r   r   r     s
    zAutocompleteMixin.__init__c             C   s(   | j j}t| j| jj|jj|jjf S )N)	rP   rX   r   url_namerQ   r&   rZ   r[   r\   )r   rX   r   r   r   get_url  s    zAutocompleteMixin.get_urlc                sb   t  j||d}|jdd |jddd| j dtj| j d|d |d rNd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#   r   true   GETzadmin-autocomplete )zdata-ajax--cachezdata-ajax--delayzdata-ajax--typezdata-ajax--urlz
data-themezdata-allow-clearzdata-placeholderr#   )r   build_attrsr^   rd   r   jsondumpsis_required)r   
base_attrsr   r   )r!   r   r   r     s    "zAutocompleteMixin.build_attrsc                s   dg df}|g}d} fdd|D } j  rR j rR|d j j|dddd  fdd	 jjj jj|d
D }x^|D ]V\}	}
t	|	|ko|dkp j}||O }t
|d }|d }|j j||	|
|| q~W |S )z9Return selected options based on the ModelChoiceIterator.Nr   Fc                s&   h | ]}t | jjjkrt |qS r   )r>   r    fieldempty_values)r   rM   )r   r   r   	<setcomp>  s   z.AutocompleteMixin.optgroups.<locals>.<setcomp>r   r   c             3   s"   | ]}|j  jjj|fV  qd S )N)rn   r    r   label_from_instance)r   rq   )r   r   r   r@     s   z.AutocompleteMixin.optgroups.<locals>.<genexpr>)pk__in)r   rz   appendcreate_optionr    querysetrS   rR   filterr>   len)r   r&   r'   attrdefaultgroupshas_selectedZselected_choicesr    option_valueoption_labelselectedindexsubgroupr   )r   r   	optgroups  s"    


zAutocompleteMixin.optgroupsc             C   sZ   t jr
dnd}tjt }|r(d| fnf }tjd| d| f| d dd	| d
fidS )Nr   z.minz"admin/js/vendor/select2/i18n/%s.jsz"admin/js/vendor/jquery/jquery%s.jsz)admin/js/vendor/select2/select2.full%s.jsadmin/js/jquery.init.jsadmin/js/autocomplete.jsZscreenz&admin/css/vendor/select2/select2%s.csszadmin/css/autocomplete.css)r   css)r   r   )r   r   SELECT2_TRANSLATIONSri   r   r   r   )r   r   Z	i18n_nameZ	i18n_filer   r   r   r     s     zAutocompleteMixin.media)N)N)r)   r*   r+   r,   r   r   r   r   r   r-   r   r.   r   r   )r!   r   r   }  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 )AutocompleteSelectMultipleN)r)   r*   r+   r   r   r   r   r     s   r   )-r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )>r,   r   r   djangor   django.confr   django.core.exceptionsr   Zdjango.core.validatorsr   django.db.models.deletionr   django.urlsr   Zdjango.urls.exceptionsr   django.utils.htmlr	   django.utils.safestringr
   django.utils.textr   django.utils.translationr   r   r8   SelectMultipler   	DateInputr/   	TimeInputr3   SplitDateTimeWidgetr5   RadioSelectr:   ClearableFileInputr;   rN   	TextInputrO   rs   Widgetry   Textarear   r   
EmailInputr   URLInputr   NumberInputr   r   r   r   rd   r   Selectr   r   r   r   r   r   <module>   sP   "KW    Z