B
    CVvgè  ã               @   sÎ   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„ ZeeƒZeƒ efdd„ƒZddddedfdd„Zdd„ Zddd„Zdd„ Zdd„ ZdS )é    N)Ú	lru_cache)Úsettings)Úflatatt)ÚContext)Úget_template)ÚSimpleLazyObject)Ú
SafeStringé   )ÚKeepContextc               C   s
   t tdƒS )NZCRISPY_TEMPLATE_PACK)Úgetattrr   © r   r   úC/tmp/pip-install-o3oxmrkh/django-crispy-forms/crispy_forms/utils.pyÚget_template_pack   s    r   c             C   s   t d|  ƒS )Nz%s/field.html)r   )Útemplate_packr   r   r   Údefault_field_template   s    r   c	          	   K   s°  |dkrg n|  ¡ }
t||
ƒ��† | dkr2tdƒS ttddƒ}t| dƒrX| j|||d�S yê||  }|j}|dk	�r@t|jd|jgƒ}|}t	|t
ƒr |gt|ƒ }xžtt||ƒƒD ]Œ\}\}}t|jdƒ�rd|krò|d d	krò| |¡|jj|< n|jj| j |¡ q°d|k�r.|d d	k�r.| |¡|_q°|jj |¡ q°W W nD tk
�r†   |�shtd
|  ƒ‚nd}tjd
|  t ¡ d� Y nX t|dƒ�rØ| |jk�r®|j | ¡ n*|�sÂtd|  ƒ‚ntjd|  t ¡ d� |dk�rìtdƒ}n¶|dk�r|jdk�rt|ƒ}n
t|jƒ}nt|ƒ}|dk	�rZt|dƒ�rRt	|jtƒ�rR|j |¡ n|g|_| ||t t	|t
ƒ�rt|ni ƒdœ¡ |dk	�r”| |¡ | | !¡ ¡}|S Q R X dS )a�  
    Renders a django-crispy-forms field

    :param field: Can be a string or a Layout object like `Row`. If it's a layout
        object, we call its render method, otherwise we instantiate a BoundField
        and render it using default template 'CRISPY_TEMPLATE_PACK/field.html'
        The field is added to a list that the form holds called `rendered_fields`
        to avoid double rendering fields.
    :param form: The form/formset to which that field belongs to.
    :template: Template used for rendering the field.
    :layout_object: If passed, it points to the Layout object that is being rendered.
        We use it to store its bound fields in a list called `layout_object.bound_fields`
    :attrs: Attributes for the field's widget
    :template_pack: Name of the template pack to be used for rendering `field`
    :extra_context: Dictionary to be added to context, added variables by the layout object
    NÚ ZCRISPY_FAIL_SILENTLYTÚrender)r   ÚwidgetsÚtypeÚhiddenz"Could not resolve form field '%s'.)Úexc_infoÚrendered_fieldsz(A field should only be rendered once: %sÚbound_fields)ÚfieldÚ
labelclassZ
flat_attrs)"Úkeysr
   r   r   r   Úhasattrr   r   ÚwidgetÚ
isinstanceÚdictÚlenÚ	enumerateÚzipZhidden_widgetr   ÚattrsÚupdateÚKeyErrorÚ	ExceptionÚloggingÚwarningÚsysr   r   ÚaddZcrispy_field_templater   r   r   ÚlistÚappendr   Úflatten)r   ÚformÚcontextÚtemplater   Zlayout_objectr#   r   Zextra_contextÚkwargsZ
added_keysZFAIL_SILENTLYZbound_fieldZfield_instancer   Z
list_attrsÚindexr   ÚattrÚhtmlr   r   r   Úrender_field   sj    









r5   c             C   s   t dd„ |  ¡ D ƒƒS )zÌ
    Convert a dictionary of attributes to a single string.

    Passed attributes are redirected to `django.forms.utils.flatatt()`
    with replaced "_" (underscores) by "-" (dashes) in their names.
    c             S   s   i | ]\}}||  d d¡“qS )Ú_ú-)Úreplace)Ú.0ÚkÚvr   r   r   ú
<dictcomp>•   s    zflatatt.<locals>.<dictcomp>)Ú_flatattÚitems)r#   r   r   r   r   Ž   s    r   c             C   sL   ddl m} |dk	r |ddƒ}n
|ddƒ}t|ƒ}| | |dœ¡ | |¡S )z�
    Renders a form and returns its HTML output.

    This function wraps the template logic in a function easy to use in a Django view.
    r   )ÚCrispyFormNodeNr.   Úhelper)r.   r@   )Z+crispy_forms.templatetags.crispy_forms_tagsr?   r   r$   r   )r.   r@   r/   r?   ÚnodeZnode_contextr   r   r   Úrender_crispy_form˜   s    
rB   c                s   ‡ fdd„| D ƒS )z…
    Take the not-in-place intersection of two lists, similar to sets but preserving order.
    Does not check unicity of list1.
    c                s   g | ]}|ˆ kr|‘qS r   r   )r9   Úitem)Úlist2r   r   ú
<listcomp>°   s    z%list_intersection.<locals>.<listcomp>r   )Zlist1rD   r   )rD   r   Úlist_intersection«   s    rF   c             C   s:   t |ƒ}g }x(| D ] }||kr| |¡ | |¡ qW |S )zm
    Take the not-in-place difference of two lists (left - right), similar to sets but preserving order.
    )Úsetr*   r,   )ÚleftÚrightZblockedÚ
differencerC   r   r   r   Úlist_difference³   s    

rK   )NN)r'   r)   Ú	functoolsr   Zdjango.confr   Zdjango.forms.utilsr   r=   Zdjango.templater   Zdjango.template.loaderr   Zdjango.utils.functionalr   Zdjango.utils.safestringr   Úbaser
   r   ZTEMPLATE_PACKr   r5   rB   rF   rK   r   r   r   r   Ú<module>   s.   h

