
    og1                         d dl Z d dlmZ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  G d d	      Z G d
 de      Zy)    N)NoReverseMatchreverse)	mark_safe)FormHelpersException)Layout)LayoutSlice)TEMPLATE_PACKflatattlist_differencerender_fieldc                   P    e Zd Zd Zd Zd ZddddZd Zd	 Zd
 Z	d Z
d Zd Zy)DynamicLayoutHandlerc                 2    | j                   t        d      y )Nz+You need to set a layout in your FormHelper)layoutr   selfs    L/var/www/medrc_site/venv/lib/python3.12/site-packages/crispy_forms/helper.py_check_layoutz"DynamicLayoutHandler._check_layout   s    ;;&'TUU     c                 R    | j                          | j                  t        d      y )Nz3You need to pass a form instance to your FormHelper)r   formr   r   s    r   _check_layout_and_formz+DynamicLayoutHandler._check_layout_and_form   s)    99&'\]] r   c           	          | 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fieldsr   s    r   allzDynamicLayoutHandler.all   s9     	4;;aT[[5G5G1H!(LMMr   r   F	max_levelgreedyc                    | j                          | j                  j                  |||      }t        | j                  |      S )zX
        Returns a LayoutSlice pointing to layout objects of type `LayoutClass`
        r   )r   r   get_layout_objectsr   )r   r    r!   LayoutClassesfiltered_layout_objectss        r   filterzDynamicLayoutHandler.filter   s@     	"&++"@"@Zclr"@"s4;;(?@@r   c                 &   | j                          | j                  j                         }g }|D ]K  }t        | j                  j
                  |j                     j                  |      s;|j                  |       M t        | j                  |      S )zX
        Returns a LayoutSlice pointing to fields with widgets of `widget_type`
        
r   r   get_field_names
isinstancer   r   namewidgetappendr   r   widget_typelayout_field_namesfiltered_fieldspointers        r   filter_by_widgetz%DynamicLayoutHandler.filter_by_widget&   s}     	##%![[88: ) 	0G$))**7<<8??M&&w/	0 4;;88r   c                 &   | j                          | j                  j                         }g }|D ]K  }t        | j                  j
                  |j                     j                  |      r;|j                  |       M t        | j                  |      S )zb
        Returns a LayoutSlice pointing to fields with widgets NOT matching `widget_type`
        r(   r.   s        r   exclude_by_widgetz&DynamicLayoutHandler.exclude_by_widget5   s}     	##%![[88: ) 	0Gdii..w||<CC[Q&&w/	0 4;;88r   c                 R   t        |t              rt        | |      rt        | |      S | j	                          | j
                  j                         }g }|D ]#  }|j                  |k(  s|j                  |       % t        | j
                  |      S t        | j
                  |      S )z{
        Return a LayoutSlice that makes changes affect the current instance of the layout
        and not a copy.
        )
r*   strhasattrgetattrr   r   r)   r+   r-   r   )r   keyr0   filtered_fieldr2   s        r   __getitem__z DynamicLayoutHandler.__getitem__D   s     c3 tS!tS)) !%!<!<!>N- 3<<3&"))'23
 t{{N;;4;;,,r   c                 "    || j                   |<   y Nr   )r   r:   values      r   __setitem__z DynamicLayoutHandler.__setitem__]   s     Cr   c                 2    | j                   j                  |= y r>   )r   r   )r   r:   s     r   __delitem__z DynamicLayoutHandler.__delitem__`   s    KKs#r   c                 Z    | j                   t        | j                   j                        S y)Nr   )r   r   r   r   s    r   __len__zDynamicLayoutHandler.__len__c   s$    ;;"t{{))**r   N)__name__
__module____qualname__r   r   r   r&   r3   r5   r<   rA   rC   rE    r   r   r   r      s?    V^
N 01 A99-2!$r   r   c                   n   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dZd Zed	        Zej@                  d
        Zed        Z!e!j@                  d        Z!ed        Z"e"j@                  d        Z"ed        Z#e#j@                  d        Z#d Z$d Z%e&fdZ'e&fdZ(y)
FormHelperaq  
    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 set 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::

                path('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.

        **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.

        **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 NTFc                 `    i | _         g | _        ||| _        | j                  |      | _        y y r>   )attrsinputsr   build_default_layoutr   r   r   s     r   __init__zFormHelper.__init__   s4    
DI33D9DK r   c                 B    t        |j                  j                          S r>   )r   r   keysrR   s     r   rQ   zFormHelper.build_default_layout   s    t{{'')**r   c                     | j                   S r>   )_form_methodr   s    r   form_methodzFormHelper.form_method   s       r   c                 h    |j                         dvrt        d      |j                         | _        y )N)getrL   zSOnly GET and POST are valid in the                     form_method helper attribute)lowerr   rW   )r   methods     r   rX   zFormHelper.form_method   s2    <<>0&2 
 #LLNr   c                 d    	 t        | j                        S # t        $ r | j                  cY S w xY wr>   )r   _form_actionr   r   s    r   form_actionzFormHelper.form_action   s3    	%4,,-- 	%$$$	%s    //c                     || _         y r>   )r^   )r   actions     r   r_   zFormHelper.form_action   s
    "r   c                     | j                   S r>   )_help_text_inliner   s    r   help_text_inlinezFormHelper.help_text_inline   s    %%%r   c                 "    || _         | | _        y r>   )rc   _error_text_inliner   flags     r   rd   zFormHelper.help_text_inline   s    !%&*(r   c                     | j                   S r>   )rf   r   s    r   error_text_inlinezFormHelper.error_text_inline   s    &&&r   c                 "    || _         | | _        y r>   )rf   rc   rg   s     r   rj   zFormHelper.error_text_inline  s    "&%)r   c                 :    | j                   j                  |       y r>   )rP   r-   )r   input_objects     r   	add_inputzFormHelper.add_input  s    <(r   c                     || _         y r>   r?   )r   r   s     r   
add_layoutzFormHelper.add_layout	  s	    r   c                 X   t               |_        | j                  |_        | j                  j                  |||      }| j                  s| j                  s| j                  rt        |j                  j                               }t        ||j                        }|D ]  }| j                  s`| j                  r#|j                  |   j                  j                  s1| j                  sK|j                  |   j                  j                  so|t!        ||||      z  } t#        |      S )zB
        Returns safe html of the rendering of the layout
        )template_pack)setrendered_fieldsfield_templatecrispy_field_templater   renderrender_unmentioned_fieldsrender_hidden_fieldsrender_required_fieldstupler   rU   r   r,   	is_hiddenis_requiredr   r   )r   r   contextrr   htmlr   left_fields_to_renderfields           r   render_layoutzFormHelper.render_layout  s      #u%)%8%8" {{!!$}!M ))T-F-F$JeJe4;;++-.F$3FD<P<P$Q!. \2211dkk%6H6O6O6Y6Y33E8J8Q8Q8]8]Lg][[D\ r   c                 ~   | j                   r| j                   j                         ni }| j                  r| j                  j                         |d<   | j                  r| j                  j                         |d<   | j
                  r| j
                  j                         |d<   | j                  r| j                  |d<   i d|d| j                  d| j                  d| j                  d	| j                  xs d
|z  dt        |      d| j                  j                         d| j                  j                         d| j                  d| j                  d| j                   d| j"                  j                         d| j$                  d| j&                  d| j(                  d| j*                  }|dk(  r_d| j
                  j-                         v r}t/        j0                  d| j(                        }|r[d}|D cg c]  }||d   |d   fz   c}|d<   n:t/        j0                  d| j(                        }|rd}|D cg c]  }||z  	 c}|d<   | j2                  r| j2                  |d<   | j4                  j7                         D ]&  \  }}||vs|d vs|j9                  d!      r"|||<   ( |S c c}w c c}w )"zD
        Used by crispy_forms_tags to get helper attributes
        ra   idclassform_group_wrapper_classrO   disable_csrfrj   field_classru   z%s/field.html
flat_attrsform_error_titlerX   form_show_errorsform_show_labelsform_tagformset_error_titlerd   include_medialabel_classuse_custom_control
bootstrap4zform-horizontalzcol(-(xl|lg|md|sm))?-(\d+)zoffset%s-%sr   bootstrap_checkbox_offsetszcol-(lg|md|sm|xs)-(\d+)zcol-%s-offset-%srP   )r   rP   _)rO   copyr_   stripform_id
form_classr   r   rj   r   ru   r
   r   rX   r   r   r   r   rd   r   r   r   splitrefindallrP   __dict__items
startswith)	r   rr   rO   r   bootstrap_size_matchoffset_patternmattribute_namer@   s	            r   get_attributeszFormHelper.get_attributes$  s    &*ZZ

!R"..446E(O<<,,,,.E$K??!__224E'N((040M0ME,-
U
D--
  !7!7
 4++	

 d11T_}5T
 '%.
  5 5 ; ; =
 4++113
  5 5
  5 5
 
 "4#;#;#A#A#C
  5 5
 T//
 4++
  !$"9"9!
& L( DOO$9$9$;;')zz2OQUQaQa'b$'%2N@T;;<!A$"6;E67 $&::.H$JZJZ#[ #!3Sg6ha~7I6h23;;"kkE(O%)]]%8%8%: 	.!NEe+"*>>&11#6(-n%	. ); 7is    J5J:r>   ))rF   rG   rH   __doc__rW   r^   r   r   r   r   r   r   r   r   r   rx   ry   rz   rc   rf   r   templateru   r   r   r   r   r   rS   rQ   propertyrX   setterr_   rd   rj   rn   rp   r	   r   r   rI   r   r   rK   rK   j   so   IV LLDGJ!FH % "HNLKKM:+ ! ! + + % % # # & & + + ' ' * *) :G 0 ,9 :r   rK   )r   django.urlsr   r   django.utils.safestringr   crispy_forms.exceptionsr   crispy_forms.layoutr   crispy_forms.layout_slicer   crispy_forms.utilsr	   r
   r   r   r   rK   rI   r   r   <module>r      s9    	 / - 8 & 1 T T[ [|t% tr   