
^Q\:                 @   s   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 m Z m Z m Z m Z y d  d l m Z m Z Wn( e k
 r d  d l m Z m Z Yn XGd	 d
   d
 e  Z Gd d   d e  Z d S)    N)	mark_safe)string_types)FormHelpersException)Layout)LayoutSlice)TEMPLATE_PACKflatattlist_differencelist_intersectionrender_field)reverseNoReverseMatchc               @   s   e  Z d  Z d d   Z d d   Z d d   Z d d   Z d	 d
   Z d d   Z d d   Z	 d d   Z
 d d   Z d d   Z d S)DynamicLayoutHandlerc             C   s"   |  j  d  k r t d   n  d  S)Nz+You need to set a layout in your FormHelper)layoutr   )self r   F/var/www/dbchiro/venv/build/django-crispy-forms/crispy_forms/helper.py_check_layout   s    z"DynamicLayoutHandler._check_layoutc             C   s,   |  j    |  j d  k r( t d   n  d  S)Nz3You need to pass a form instance to your FormHelper)r   formr   )r   r   r   r   _check_layout_and_form   s    
z+DynamicLayoutHandler._check_layout_and_formc             C   s2   |  j    t |  j t d t |  j j  d   S)zD
        Returns all layout objects of first level of depth
        r      )r   r   r   slicelenfields)r   r   r   r   all   s    
zDynamicLayoutHandler.allc             O   s\   |  j    | j d d  } | j d d  } |  j j | d | d | } t |  j |  S)zX
        Returns a LayoutSlice pointing to layout objects of type `LayoutClass`
        	max_levelr   greedyF)r   popr   Zget_layout_objectsr   )r   ZLayoutClasseskwargsr   r   Zfiltered_layout_objectsr   r   r   filter&   s
    
zDynamicLayoutHandler.filterc             C   sp   |  j    |  j j   } g  } x> | D]6 } t |  j j | d j |  r& | j |  q& q& Wt |  j |  S)zX
        Returns a LayoutSlice pointing to fields with widgets of `widget_type`
        r   )	r   r   get_field_names
isinstancer   r   widgetappendr   )r   widget_typelayout_field_namesfiltered_fieldspointerr   r   r   filter_by_widget1   s    
 z%DynamicLayoutHandler.filter_by_widgetc             C   sp   |  j    |  j j   } g  } x> | D]6 } t |  j j | d j |  s& | j |  q& q& Wt |  j |  S)zb
        Returns a LayoutSlice pointing to fields with widgets NOT matching `widget_type`
        r   )	r   r   r    r!   r   r   r"   r#   r   )r   r$   r%   r&   r'   r   r   r   exclude_by_widget@   s    
 z&DynamicLayoutHandler.exclude_by_widgetc             C   s   t  | t  r t |  |  r+ t |  |  S|  j   |  j j   } g  } x@ | D]8 } t |  d k rQ | d | k rQ | j |  qQ qQ Wt	 |  j |  St	 |  j |  S)z{
        Return a LayoutSlice that makes changes affect the current instance of the layout
        and not a copy.
           r   )
r!   r   hasattrgetattrr   r   r    r   r#   r   )r   keyr%   Zfiltered_fieldr'   r   r   r   __getitem__O   s    
"z DynamicLayoutHandler.__getitem__c             C   s   | |  j  | <d  S)N)r   )r   r-   valuer   r   r   __setitem__h   s    z DynamicLayoutHandler.__setitem__c             C   s   |  j  j | =d  S)N)r   r   )r   r-   r   r   r   __delitem__k   s    z DynamicLayoutHandler.__delitem__c             C   s'   |  j  d  k	 r t |  j  j  Sd Sd  S)Nr   )r   r   r   )r   r   r   r   __len__n   s    zDynamicLayoutHandler.__len__N)__name__
__module____qualname__r   r   r   r   r(   r)   r.   r0   r1   r2   r   r   r   r   r      s   r   c               @   s  e  Z d  Z d Z d Z d Z d Z d Z d Z d Z	 d Z
 d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d d d	  Z d
 d   Z e d d    Z  e  j! d d    Z  e d d    Z" e" j! d d    Z" e d d    Z# e# j! d d    Z# e d d    Z$ e$ j! d d    Z$ e d d    Z% e% j! d d    Z% d d   Z& d d   Z' e( d d   Z) e( d! d"  Z* d S)#
FormHelperaj  
    This class controls the form rendering behavior of the form passed to
    the `{% crispy %}` tag. For doing so you will need to set its attributes
    and pass the corresponding helper object to the tag::

        {% crispy form form.helper %}

    Let's see what attributes you can set and what form behaviors they apply to:

        **form_method**: Specifies form method attribute.
            You can see it to 'POST' or 'GET'. Defaults to 'POST'

        **form_action**: Applied to the form action attribute:
            - Can be a named url in your URLconf that can be executed via the `{% url %}` template tag.             Example: 'show_my_profile'. In your URLconf you could have something like::

                url(r'^show/profile/$', 'show_my_profile_view', name = 'show_my_profile')

            - It can simply point to a URL '/whatever/blabla/'.

        **form_id**: Generates a form id for dom identification.
            If no id provided then no id attribute is created on the form.

        **form_class**: String containing separated CSS classes to be applied
            to form class attribute. The form will always have by default
            'uniForm' class.

        **form_group_wrapper_class**: String containing separated CSS classes to be applied
            to each row of inputs.

        **form_tag**: It specifies if <form></form> tags should be rendered when using a Layout.
            If set to False it renders the form without the <form></form> tags. Defaults to True.

        **form_error_title**: If a form has `non_field_errors` to display, they
            are rendered in a div. You can set title's div with this attribute.
            Example: "Oooops!" or "Form Errors"

        **formset_error_title**: If a formset has `non_form_errors` to display, they
            are rendered in a div. You can set title's div with this attribute.

        **form_style**: Uni-form has two built in different form styles. You can choose
            your favorite. This can be set to "default" or "inline". Defaults to "default".

        **include_media**: Whether to automatically include form media. Set to False if
            you want to manually include form media outside the form. Defaults to True.

    Public Methods:

        **add_input(input)**: You can add input buttons using this method. Inputs
            added using this method will be rendered at the end of the form/formset.

        **add_layout(layout)**: You can add a `Layout` object to `FormHelper`. The Layout
            specifies in a simple, clean and DRY way how the form fields should be rendered.
            You can wrap fields, order them, customize pretty much anything in the form.

    Best way to add a helper to a form is adding a property named helper to the form
    that returns customized `FormHelper` object::

        from crispy_forms.helper import FormHelper
        from crispy_forms.layout import Submit

        class MyForm(forms.Form):
            title = forms.CharField(_("Title"))

            @property
            def helper(self):
                helper = FormHelper()
                helper.form_id = 'this-form-rocks'
                helper.form_class = 'search'
                helper.add_input(Submit('save', 'save'))
                [...]
                return helper

    You can use it in a template doing::

        {% load crispy_forms_tags %}
        {% crispy form %}
    post defaultNTFc             C   s@   i  |  _  g  |  _ | d  k	 r< | |  _ |  j |  |  _ n  d  S)N)attrsinputsr   build_default_layoutr   )r   r   r   r   r   __init__   s
    			zFormHelper.__init__c             C   s   t  | j j     S)N)r   r   keys)r   r   r   r   r   r<      s    zFormHelper.build_default_layoutc             C   s   |  j  S)N)_form_method)r   r   r   r   form_method   s    zFormHelper.form_methodc             C   s4   | j    d k r! t d   n  | j    |  _ d  S)Ngetr7   zSOnly GET and POST are valid in the                     form_method helper attribute)zgetzpost)lowerr   r?   )r   methodr   r   r   r@      s    c             C   s1   y t  |  j  SWn t k
 r, |  j SYn Xd  S)N)r   _form_actionr   )r   r   r   r   form_action   s    zFormHelper.form_actionc             C   s   | |  _  d  S)N)rD   )r   actionr   r   r   rE      s    c             C   s*   |  j  d k r d S|  j  d k r& d Sd  S)Nr9   r8   inlineZinlineLabels)_form_style)r   r   r   r   
form_style   s    zFormHelper.form_stylec             C   s4   | j    d k r! t d   n  | j    |  _ d  S)Nr9   rG   zXOnly default and inline are valid in the                     form_style helper attribute)zdefaultzinline)rB   r   rH   )r   styler   r   r   rI     s    c             C   s   |  j  S)N)_help_text_inline)r   r   r   r   help_text_inline  s    zFormHelper.help_text_inlinec             C   s   | |  _  | |  _ d  S)N)rK   _error_text_inline)r   flagr   r   r   rL     s    	c             C   s   |  j  S)N)rM   )r   r   r   r   error_text_inline  s    zFormHelper.error_text_inlinec             C   s   | |  _  | |  _ d  S)N)rM   rK   )r   rN   r   r   r   rO     s    	c             C   s   |  j  j |  d  S)N)r;   r#   )r   Zinput_objectr   r   r   	add_input"  s    zFormHelper.add_inputc             C   s   | |  _  d  S)N)r   )r   r   r   r   r   
add_layout%  s    zFormHelper.add_layoutc          	   C   s  t    | _ |  j | _ |  j j | |  j | d | } |  j sT |  j sT |  j	 r t  | j
 j    } | | j } xw | D]l } |  j s |  j r | j
 | j j s |  j	 r} | j
 | j j r} | t | | |  j | d | 7} q} q} Wn  t | d  rt | j d  rt t | d i   j    } t | j d  }	 t | |	  }
 t |
 | j  } xq | D]f } |  j s|  j r| j
 | j j s|  j	 ri| j
 | j j ri| t | | |  j |  7} qiqiWqn  t |  S)zB
        Returns safe html of the rendering of the layout
        template_packMetar   )setZrendered_fieldsfield_templateZcrispy_field_templater   renderrI   render_unmentioned_fieldsrender_hidden_fieldsrender_required_fieldsr   r>   r"   Z	is_hiddenZis_requiredr   r+   rS   tupler,   r
   r	   r   )r   r   contextrR   htmlr   Zleft_fields_to_renderfieldZcurrent_fieldsZmeta_fieldsZfields_to_renderr   r   r   render_layout(  sD    						)zFormHelper.render_layoutc             C   s  i |  j  j   d 6|  j d 6|  j j   d 6|  j d 6|  j d 6|  j d 6|  j d 6|  j d 6|  j	 d	 6|  j
 d
 6|  j d 6|  j d 6} t j d |  j
  } | r d d   | D | d <n  i  | d <|  j r |  j j   | d <n  |  j r|  j j   | d d <n  |  j r.|  j j   | d d <n  |  j r{| d k rad |  j j   | d d <q|  j j   | d d <n0 | d k r|  j j d d  d | d d <n  |  j r|  j | d d <n  t | d  | d <|  j r|  j | d <n  |  j r|  j j   | d <n  |  j r3|  j j   | d <n  xR |  j j   D]A \ } } | | k rC| d  k rC| j d  rC| | | <qCqCW| S)!zD
        Used by crispy_forms_tags to get helper attributes
        r@   form_tagrI   form_show_errorsrL   rO   html5_requiredform_show_labelsdisable_csrflabel_classfield_classinclude_mediazcol-(lg|md|sm|xs)-(\d+)c             S   s   g  |  ] } d  |  q S)zcol-%s-offset-%sr   ).0mr   r   r   
<listcomp>u  s   	 z-FormHelper.get_attributes.<locals>.<listcomp>Zbootstrap_checkbox_offsetsr:   rF   idZuni_formz
uniForm %sclassr8   z uniFormform_group_wrapper_classZ
flat_attrsr;   form_error_titleformset_error_titler   _)zlayoutzinputs)r@   stripr_   rI   r`   rL   rO   ra   rb   rc   rd   re   rf   refindallr:   copyrE   form_id
form_classrA   rl   r   r;   rm   rn   __dict__items
startswith)r   rR   rw   Zbootstrap_size_matchZattribute_namer/   r   r   r   get_attributesa  sT    









				$				(zFormHelper.get_attributes)+r3   r4   r5   __doc__r?   rD   rH   r   rt   ru   rl   r   r_   rm   rn   r`   rW   rX   rY   rK   rM   ra   rb   templaterU   rc   rd   re   rf   r=   r<   propertyr@   setterrE   rI   rL   rO   rP   rQ   r   r^   ry   r   r   r   r   r6   u   sT   N9r6   )rq   Zdjango.utils.safestringr   Zcrispy_forms.compatibilityr   Zcrispy_forms.exceptionsr   Zcrispy_forms.layoutr   Zcrispy_forms.layout_slicer   Zcrispy_forms.utilsr   r   r	   r
   r   Zdjango.urlsr   r   ImportErrorZdjango.core.urlresolversobjectr   r6   r   r   r   r   <module>   s   (`