3
(h4<                 @   sz  d dl m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 yd d	lmZ W n  ek
r   d d	lmZ Y nX 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Z dd Z!G dd dej"j#Z$G dd dej%j&Z'G dd dej"j(Z)G dd dej%j&Z*G dd dej#Z+G dd dej&Z,dd  Z-d!d" Z.d#d$ Z/d%d& Z0dS )'    )unicode_literalsN)registry)forms)settings)ContentType)reverse)QuerySet)flatatt)render_to_string)force_escape)
force_text)	mark_safe)	text_type)ugettextzEnter text to search.c             C   s:   d}yt jsd}W n tk
r&   Y nX tjddi|dS )	Najax_select/js/bootstrap.jsajax_select/js/ajax_select.jsallajax_select/css/ajax_select.css)cssjs)r   r   )r   )r   )r   ZAJAX_SELECT_BOOTSTRAPAttributeErrorr   ZMedia)selfr    r   C/tmp/pip-install-q3hcpn_q/django-ajax-selects/ajax_select/fields.py_media   s    r   c                   sH   e Zd ZdZeeZdZd fdd	ZdddZ	d	d
 Z
dd Z  ZS )AutoCompleteSelectWidgetzJWidget to search for a model and return it as text for use in a CharField.N Tc                s6   |pi | _ ttjj| j|| || _|| _|| _d S )N)	plugin_optionssuperr   widgets	TextInput__init__channel	help_textshow_help_text)r   r"   r#   r$   r   argskwargs)	__class__r   r   r!   1   s
    
z!AutoCompleteSelectWidget.__init__c             C   s   |pd}| j |}|jd|| _d}d }tj| j}|r|j|g}y|d }	W n$ tk
rt   td||f Y nX |j	|	}||	j
g}| jr| j}
nd}
|| j|||
tt|| jjdd| jd}|jt|| j| j| d| j df}t||}t|S )	Nr   idr   z%s cannot find object:%s-)namehtml_id
current_idcurrent_reprr#   extra_attrs	func_slugadd_linkz&ajax_select/autocompleteselect_%s.htmlz#ajax_select/autocompleteselect.html)build_attrspopr+   r   getr"   get_objects
IndexError	Exceptionformat_item_displaypkr$   r#   r   r	   replacer0   updatemake_plugin_optionsr   r
   )r   r*   valueattrsfinal_attrsr-   initiallookupobjsobjr#   context	templatesoutr   r   r   render>   s<    





zAutoCompleteSelectWidget.renderc             C   s   |j |d S )N)r3   )r   datafilesr*   r   r   r   value_from_datadicte   s    z,AutoCompleteSelectWidget.value_from_datadictc             C   s   d| S )Nz%s_textr   )r   id_r   r   r   id_for_labelh   s    z%AutoCompleteSelectWidget.id_for_label)r   TN)N)__name__
__module____qualname____doc__propertyr   mediar0   r!   rF   rI   rK   __classcell__r   r   )r'   r   r   )   s     	
'r   c                   s<   e Zd ZdZdZ fddZdd Zdd Zd	d
 Z  Z	S )AutoCompleteSelectFieldz7Form field to select a Model for a ForeignKey db field.Nc                sp   || _ t||jdtt|jdd|jdi d}|j|jdi  tf ||d< tt	| j
|dd	i| d S )
Nr#   r$   Tr   )r"   r#   r$   r   widget_optionswidget
max_length   )r"   dictr3   _as_default_helpr2   r:   r   r   rS   r!   )r   r"   r%   r&   widget_kwargs)r'   r   r   r!   r   s    
z AutoCompleteSelectField.__init__c             C   s`   |rBt j| j}|j|g}t|dkr:tjd||f |d S | jrXtj| jd d S d S )N   z%s cannot find object: %sr   required)	r   r3   r"   r4   lenr   ValidationErrorr]   error_messages)r   r<   r@   rA   r   r   r   clean   s    zAutoCompleteSelectField.cleanc             C   s   t | || d S )N)_check_can_add)r   usermodelr   r   r   check_can_add   s    z%AutoCompleteSelectField.check_can_addc             C   s0   |d k	r|nd}|d k	r|nd}t |t |kS )Nr   )r   )r   r?   rG   initial_value
data_valuer   r   r   has_changed   s    z#AutoCompleteSelectField.has_changed)
rL   rM   rN   rO   r"   r!   ra   re   rh   rR   r   r   )r'   r   rS   l   s   rS   c                   sH   e Zd ZdZeeZdZd fdd	ZdddZ	d	d
 Z
dd Z  ZS ) AutoCompleteSelectMultipleWidgetz;Widget to select multiple models for a ManyToMany db field.Nr   Tc                s2   t t| j|| || _|| _|| _|p*i | _d S )N)r   ri   r!   r"   r#   r$   r   )r   r"   r#   r$   r   r%   r&   )r'   r   r   r!      s
    z)AutoCompleteSelectMultipleWidget.__init__c          
      s   |d krg }| j |}|jd|| _tj| j t|tr@|}n
 j|}t	dd |D } fdd|D }| j
r|| j}nd}|| j||ttj||tt|| jjdd| jd	}	|	jt | j| j| d| j d	f}
t|
|	}t|S )
Nr(   c             S   s   g | ]
}|j qS r   )r8   ).0rB   r   r   r   
<listcomp>   s    z;AutoCompleteSelectMultipleWidget.render.<locals>.<listcomp>c                s   g | ]} j ||jgqS r   )r7   r8   )rj   rB   )r@   r   r   rk      s   r   r)   )	r*   r+   currentcurrent_idsZcurrent_reprsr#   r.   r/   r0   z.ajax_select/autocompleteselectmultiple_%s.htmlz+ajax_select/autocompleteselectmultiple.html)r1   r2   r+   r   r3   r"   
isinstancer   r4   pack_idsr$   r#   r   jsondumpsr	   r9   r0   r:   r;   r   r
   )r   r*   r<   r=   r>   objectsrm   r?   r#   rC   rD   rE   r   )r@   r   rF      s8    






z'AutoCompleteSelectMultipleWidget.renderc             C   s   dd |j |djdD S )Nc             S   s   g | ]}|r|qS r   r   )rj   valr   r   r   rk      s    zHAutoCompleteSelectMultipleWidget.value_from_datadict.<locals>.<listcomp>r   |)r3   split)r   rG   rH   r*   r   r   r   rI      s    z4AutoCompleteSelectMultipleWidget.value_from_datadictc             C   s   d| S )Nz%s_textr   )r   rJ   r   r   r   rK      s    z-AutoCompleteSelectMultipleWidget.id_for_label)r   TN)N)rL   rM   rN   rO   rP   r   rQ   r0   r!   rF   rI   rK   rR   r   r   )r'   r   ri      s     

-ri   c                   s<   e Zd ZdZdZ fddZdd Zdd Zd	d
 Z  Z	S )AutoCompleteSelectMultipleFieldz@ form field to select multiple models for a ManyToMany db field Nc                s   || _ |jd}|jdd}|d k	rt|tr6t|}|dkrt|tsV|jtj	}n|}d}t
|jtj	}||kr|j|dj }	|	r|	}qd}d}nt
t}||||jdi d}
|
j|jdi  tf |
|d	< ||d< tt| j|| d S )
Nr#   r$   Fr   zDHold down "Control", or "Command" on a Mac, to select more than one.r   )r"   r#   r$   r   rT   rU   )r"   r3   r2   rn   strr   r   	translater   ZLANGUAGE_CODErY   r9   striprZ   r:   ri   r   rv   r!   )r   r"   r%   r&   r#   r$   Z
translatedZdhZdjango_default_helpZcleaned_helpr[   )r'   r   r   r!      s6    


z(AutoCompleteSelectMultipleField.__init__c             C   s    | r| j rtj| jd |S )Nr]   )r]   r   r_   r`   )r   r<   r   r   r   ra     s    z%AutoCompleteSelectMultipleField.cleanc             C   s   t | || d S )N)rb   )r   rc   rd   r   r   r   re   $  s    z-AutoCompleteSelectMultipleField.check_can_addc             C   s,   dd |pg D }dd |pg D }||kS )Nc             S   s   g | ]}t |qS r   )r   )rj   vr   r   r   rk   )  s    z?AutoCompleteSelectMultipleField.has_changed.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )r   )rj   rz   r   r   r   rk   *  s    r   )r   rf   rg   ZivsZdvsr   r   r   rh   '  s    z+AutoCompleteSelectMultipleField.has_changed)
rL   rM   rN   rO   r"   r!   ra   re   rh   rR   r   r   )r'   r   rv      s   3rv   c                   s>   e Zd ZdZeeZdZdZdZ	 fddZ
dddZ  ZS )	AutoCompleteWidgetz
    Widget to select a search result and enter the result as raw text in the text input field.
    the user may also simply enter text and ignore any auto complete suggestions.
    Nr   c                sF   || _ |jdd| _|jdd| _|jdi | _tt| j|| d S )Nr#   r   r$   Tr   )r"   r2   r#   r$   r   r   r{   r!   )r   r"   r%   r&   )r'   r   r   r!   =  s
    zAutoCompleteWidget.__init__c       
   	   C   s   |pd}| j |}|jd|| _tj| j}| jr:| j}nd}|||| j|tt	|| jj
ddd}|jt|| j| j| d| j df}	tt|	|S )Nr   r(   r)   )r-   r,   r#   r+   r*   r.   r/   z ajax_select/autocomplete_%s.htmlzajax_select/autocomplete.html)r1   r2   r+   r   r3   r"   r$   r#   r   r	   r9   r:   r;   r   r
   )
r   r*   r<   r=   r?   r>   r@   r#   rC   rD   r   r   r   rF   E  s$    

zAutoCompleteWidget.render)N)rL   rM   rN   rO   rP   r   rQ   r"   r#   r+   r!   rF   rR   r   r   )r'   r   r{   0  s   r{   c                   s$   e Zd ZdZdZ fddZ  ZS )AutoCompleteFieldzm
    A CharField that uses an AutoCompleteWidget to lookup matching and stores the result as plain text.
    Nc                s   || _ t|jdtt|jdd|jdi d}|j|jdi  d|krX|jd|d< t|f|}d|d	}|j| tt	| j
|| d S )
Nr#   r$   Tr   )r#   r$   r   rT   r=   rW   )rV   rU   )r"   rX   r3   rY   rZ   r2   r:   r{   r   r|   r!   )r   r"   r%   r&   r[   rU   defaults)r'   r   r   r!   g  s    


zAutoCompleteField.__init__)rL   rM   rN   rO   r"   r!   rR   r   r   )r'   r   r|   a  s   r|   c             C   sz   t j| j}t|dr$|j||}n"tjj|}|jd|j	|j
f }|rv|jj	}|jjj }td||f d | j_dS )z
    Check if the User can create a related_model.

    If the LookupChannel implements check_can_add() then use this.

    Else uses Django's default permission system.

    If it can add, then enable the widget to show the green + link
    can_addz	%s.add_%szadmin:%s_%s_addz	?_popup=1N)r   r3   r"   hasattrr~   r   rr   Zget_for_modelZhas_perm	app_labelrd   _metaZobject_namelowerr   rU   r0   )r   rc   Zrelated_modelr@   r~   ctyper   rd   r   r   r   rb   |  s    

rb   c             C   sF   x@| j j D ]2\}}t|ttfr|jj|}|j||jj	 qW dS )z
    Check the form's fields for any autoselect fields and enable their
    widgets with green + button if permissions allow then to create the related_model.
    N)
Zdeclared_fieldsitemsrn   rv   rS   r   	get_fieldre   relZto)formrd   rc   r*   Z
form_fieldZdb_fieldr   r   r   autoselect_fields_check_can_add  s    r   c             C   s~   i }|r||d< |j t| di  |j | |jdsJtdd|id|d< |jddkr`d	|d< ttj|ttj|d
S )zA Make a JSON dumped dict of all options for the jQuery ui plugin.r?   r   sourceZajax_lookupr"   )r&   htmlNT)r   Zdata_plugin_options)r:   getattrr3   r   r   rp   rq   r   )r@   Zchannel_nameZwidget_plugin_optionsr?   Zpor   r   r   r;     s    

r;   c             C   s(   | r ddj dd | D  d S dS d S )Nrt   c             s   s   | ]}t |V  qd S )N)rw   )rj   r8   r   r   r   	<genexpr>  s    zpack_ids.<locals>.<genexpr>)join)idsr   r   r   ro     s    ro   )1
__future__r   rp   Zajax_select.registryr   Zdjangor   Zdjango.confr   Z"django.contrib.contenttypes.modelsr   Zdjango.core.urlresolversr   Zdjango.db.models.queryr   Zdjango.forms.utilsr	   ImportErrorZdjango.forms.utilZdjango.template.loaderr
   Zdjango.template.defaultfiltersr   Zdjango.utils.encodingr   Zdjango.utils.safestringr   Zdjango.utils.sixr   Zdjango.utils.translationr   rY   rZ   r   r   r    r   fieldsZ	CharFieldrS   ZSelectMultipleri   rv   r{   r|   rb   r   r;   ro   r   r   r   r   <module>   s:   C/KJ1