U
    }HaA                     @   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 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   )KeepContextc                   C   s   t tddS )NZCRISPY_TEMPLATE_PACKZ	bootstrap)getattrr    r   r   6/tmp/pip-unpacked-wheel-rp2i33ek/crispy_forms/utils.pyget_template_pack   s    r   c                 C   s   t d|  S )Nz%s/field.htmlr   template_packr   r   r   default_field_template   s    r   c
              
   K   s  |	dkrg n|	  }t|| | dkr8W 5 Q R  dS ttdd}t| drl| j||||dW  5 Q R  S z||  }|j}|dk	rTt|jd|jg}|}t|t	r|gt
| }tt||D ]\}\}}t|jdrd|kr|d d	kr|||jj|< n|jj| j| qd|krD|d d	krD|||_q|jj| qW nD tk
r   |s|td
|  nd}tjd
|  t d Y nX t|dr| |jkr|j|  n*|std|  ntjd|  t d |dkrd}n|dkr(|jdkrt|}n
t|j}nt|}|dk	rjt|drbt|jtrb|j| n|g|_|||tt|t	r|ni d |	dk	r||	 |  }||}|W  5 Q 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.
    :param form_style: A way to pass style name to the CSS framework used.
    :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renderr   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   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   formZ
form_style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   sp    









r6   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/   rA   )Z+crispy_forms.templatetags.crispy_forms_tagsr@   r   r%   r   )r/   rA   r0   r@   nodeZnode_contextr   r   r   render_crispy_form   s    
rC   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   )r:   itemlist2r   r   
<listcomp>   s      z%list_intersection.<locals>.<listcomp>r   )Zlist1rF   r   rE   r   list_intersection   s    rH   c                 C   s6   t |}g }| D ] }||kr|| || q|S )zm
    Take the not-in-place difference of two lists (left - right), similar to sets but preserving order.
    )setr+   r-   )leftrightZblocked
differencerD   r   r   r   list_difference   s    
rM   )NN)r(   r*   	functoolsr   Zdjango.confr   Zdjango.forms.utilsr   r>   Zdjango.templater   Zdjango.template.loaderr   Zdjango.utils.functionalr   baser
   r   ZTEMPLATE_PACKr   r6   rC   rH   rM   r   r   r   r   <module>   s.   	
t

