class PrependedAppendedText(Field):
class AppendedText(PrependedAppendedText):
class PrependedText(PrependedAppendedText):
class FormActions(LayoutObject):
class InlineCheckboxes(Field):
class InlineRadios(Field):
class FieldWithButtons(Div):
class StrictButton(TemplateNameMixin):
class Container(Div):
class ContainerHolder(Div):
class Tab(Container):
class TabHolder(ContainerHolder):
class AccordionGroup(Container):
class Accordion(ContainerHolder):
class Alert(Div):
class UneditableField(Field):
class InlineField(Field):
class Modal(LayoutObject):
    def __init__(self, field, prepended_text=None, appended_text=None, input_size=None, *args, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, extra_context=None, **kwargs):
    def __init__(self, field, text, *args, **kwargs):
    def __init__(self, field, text, *args, **kwargs):
    def __init__(self, *fields, css_id=None, css_class=None, template=None, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
    def __init__(self, *fields, input_size=None, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, extra_context=None, **kwargs):
    def __init__(self, content, css_id=None, css_class=None, template=None, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
    def __init__(self, name, *fields, **kwargs):
    def __contains__(self, field_name):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
    def first_container_with_errors(self, errors):
    def open_target_group_for_form(self, form):
    def render_link(self, template_pack=TEMPLATE_PACK, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
    def __init__(self, *args, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
    def __init__(self, content, dismiss=True, block=False, **kwargs):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
    def __init__(self, field, *args, **kwargs):
    def __init__(
        self,
        *fields,
        template=None,
        css_id="modal_id",
        title="Modal Title",
        title_id="modal_title_id",
        css_class="",
        title_class="",
        **kwargs,
    ):
    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs): class FormHelper(DynamicLayoutHandler):
    """
    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 %}
    """

    _form_method = "post"
    _form_action = ""

    form = None
    form_id = ""
    form_class = ""
    form_group_wrapper_class = ""
    layout = None
    form_tag = True
    form_error_title = None
    formset_error_title = None
    form_show_errors = True
    render_unmentioned_fields = False
    render_hidden_fields = False
    render_required_fields = False
    _help_text_inline = False
    _error_text_inline = True
    form_show_labels = True
    template = None
    field_template = None
    disable_csrf = False
    use_custom_control = True
    label_class = ""
    field_class = ""
    include_media = True

    def __init__(self, form=None):
        self.attrs = {}
        self.inputs = []

        if form is not None:
            self.form = form
            self.layout = self.build_default_layout(form)

    def build_default_layout(self, form):
        return Layout(*form.fields.keys())

    @property
    def form_method(self):
        return self._form_method

    @form_method.setter
    def form_method(self, method):
        if method.lower() not in ("get", "post"):
            raise FormHelpersException(
                "Only GET and POST are valid in the \
                    form_method helper attribute"
            )

        self._form_method = method.lower()

    @property
    def form_action(self):
        try:
            return reverse(self._form_action)
        except NoReverseMatch:
            return self._form_action

    @form_action.setter
    def form_action(self, action):
        self._form_action = action

    @property
    def help_text_inline(self):
        return self._help_text_inline

    @help_text_inline.setter
    def help_text_inline(self, flag):
        self._help_text_inline = flag
        self._error_text_inline = not flag

    @property
    def error_text_inline(self):
        return self._error_text_inline

    @error_text_inline.setter
    def error_text_inline(self, flag):
        self._error_text_inline = flag
        self._help_text_inline = not flag

    def add_input(self, input_object):
        self.inputs.append(input_object)

    def add_layout(self, layout):
        self.layout = layout

    def render_layout(self, form, context, template_pack=TEMPLATE_PACK):
        """
        Returns safe html of the rendering of the layout
        """
        form.rendered_fields = set()
        form.crispy_field_template = self.field_template

        # This renders the specified Layout strictly
        html = self.layout.render(form, context, template_pack=template_pack)

        # Rendering some extra fields if specified
        if self.render_unmentioned_fields or self.render_hidden_fields or self.render_required_fields:
            fields = tuple(form.fields.keys())
            left_fields_to_render = list_difference(fields, form.rendered_fields)
            for field in left_fields_to_render:
                if (
                    self.render_unmentioned_fields
                    or (self.render_hidden_fields and form.fields[field].widget.is_hidden)
                    or (self.render_required_fields and form.fields[field].widget.is_required)
                ):
                    html += render_field(field, form, context, template_pack=template_pack)

        return mark_safe(html)

    def get_attributes(self, template_pack=TEMPLATE_PACK):  # noqa: C901
        """
        Used by crispy_forms_tags to get helper attributes
        """
        items = {
            "disable_csrf": self.disable_csrf,
            "error_text_inline": self.error_text_inline,
            "field_class": self.field_class,
            "field_template": self.field_template or "%s/field.html" % template_pack,
            "form_method": self.form_method.strip(),
            "form_show_errors": self.form_show_errors,
            "form_show_labels": self.form_show_labels,
            "form_tag": self.form_tag,
            "help_text_inline": self.help_text_inline,
            "include_media": self.include_media,
            "label_class": self.label_class,
            "use_custom_control": self.use_custom_control,
        }

        if template_pack == "bootstrap4":
            if "form-horizontal" in self.form_class.split():
                bootstrap_size_match = re.findall(r"col(-(xl|lg|md|sm))?-(\d+)", self.label_class)
                if bootstrap_size_match:
                    offset_pattern = "offset%s-%s"
                    items["bootstrap_checkbox_offsets"] = [
                        offset_pattern % (m[0], m[-1]) for m in bootstrap_size_match
                    ]
        else:
            bootstrap_size_match = re.findall(r"col-(lg|md|sm|xs)-(\d+)", self.label_class)
            if bootstrap_size_match:
                offset_pattern = "col-%s-offset-%s"
                items["bootstrap_checkbox_offsets"] = [offset_pattern % m for m in bootstrap_size_match]

        items["attrs"] = {}
        if self.attrs:
            items["attrs"] = self.attrs.copy()
        if self.form_action:
            items["attrs"]["action"] = self.form_action.strip()
        if self.form_id:
            items["attrs"]["id"] = self.form_id.strip()
        if self.form_class:
            items["attrs"]["class"] = self.form_class.strip()
        if self.form_group_wrapper_class:
            items["attrs"]["form_group_wrapper_class"] = self.form_group_wrapper_class

        items["flat_attrs"] = flatatt(items["attrs"])

        if self.inputs:
            items["inputs"] = self.inputs
        if self.form_error_title:
            items["form_error_title"] = self.form_error_title.strip()
        if self.formset_error_title:
            items["formset_error_title"] = self.formset_error_title.strip()

        for attribute_name, value in self.__dict__.items():
            if (
                attribute_name not in items
                and attribute_name not in ["layout", "inputs"]
                and not attribute_name.startswith("_")
            ):
                items[attribute_name] = value

        return items class HTML:
    """
    Layout object. It can contain pure HTML and it has access to the whole
    context of the page where the form is being rendered.

    Examples::

        HTML("{% if saved %}Data saved{% endif %}")
        HTML('<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />')
    """

    def __init__(self, html):
        self.html = html

    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
        return Template(str(self.html)).render(context) class ButtonHolder(LayoutObject):
    """
    Layout object. It wraps fields in a <div class="buttonHolder">

    This is where you should put Layout objects that render to form buttons

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.

    Parameters
    ----------
    *fields : HTML or BaseInput
        The layout objects to render within the ``ButtonHolder``. It should
        only hold `HTML` and `BaseInput` inherited objects.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.

    Examples
    --------

    An example using ``ButtonHolder`` in your layout::

        ButtonHolder(
            HTML(<span style="display: hidden;">Information Saved</span>),
            Submit('Save', 'Save')
        )
    """

    template = "%s/layout/buttonholder.html"

    def __init__(self, *fields, css_id=None, css_class=None, template=None):
        self.fields = list(fields)
        self.css_id = css_id
        self.css_class = css_class
        self.template = template or self.template

    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
        html = self.get_rendered_fields(form, context, template_pack, **kwargs)

        template = self.get_template_name(template_pack)
        context.update({"buttonholder": self, "fields_output": html})

        return render_to_string(template, context.flatten()) class Column(Div):
    """
    Layout object. It wraps fields in a ``<div>`` and the template adds the
    appropriate class to render the contents in a column. e.g. ``col-md`` when
    using the Bootstrap4 template pack.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. If using the Bootstrap4 template pack the default
        ``col-md`` is removed if this string contins another ``col-`` class.
        By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Column('form_field_1', 'form_field_2', css_id='col-example')

    It is also possible to nest Layout Objects within a Row::

        Div(
            Column(
                Field('form_field', css_class='field-class'),
                css_class='col-sm,
            ),
            Column('form_field_2', css_class='col-sm'),
        )
    """

    template = "%s/layout/column.html" class Div(LayoutObject):
    """
    Layout object. It wraps fields in a ``<div>``.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Div(
            'form_field_1',
            'form_field_2',
            css_id='div-example',
            css_class='divs',
        )

    It is also possible to nest Layout Objects within a Div::

        Div(
            Div(
                Field('form_field', css_class='field-class'),
                css_class='div-class',
            ),
            Div('form_field_2', css_class='div-class'),
        )
    """

    template = "%s/layout/div.html"
    css_class = None

    def __init__(self, *fields, css_id=None, css_class=None, template=None, **kwargs):
        self.fields = list(fields)

        if self.css_class and css_class:
            self.css_class += f" {css_class}"
        elif css_class:
            self.css_class = css_class

        self.css_id = css_id
        self.template = template or self.template
        self.flat_attrs = flatatt(kwargs)

    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
        fields = self.get_rendered_fields(form, context, template_pack, **kwargs)

        template = self.get_template_name(template_pack)
        return render_to_string(template, {"div": self, "fields": fields}) class Fieldset(LayoutObject):
    """
    A layout object which wraps fields in a ``<fieldset>``

    Parameters
    ----------
    legend : str
        The content of the fieldset's ``<legend>``. This text is context
        aware, to bring this to life see the examples section.
    *fields : str
        Any number of fields as positional arguments to be rendered within
        the ``<fieldset>``
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<fieldset>``.

    Examples
    --------

    The Fieldset Layout object is added to your ``Layout`` for example::

        Fieldset("Text for the legend",
            "form_field_1",
            "form_field_2",
            css_id="my-fieldset-id",
            css_class="my-fieldset-class",
            data="my-data"
        )

    The above layout will be rendered as::

        '''
        <fieldset id="fieldset-id" class="my-fieldset-class" data="my-data">
           <legend>Text for the legend</legend>
           # form fields render here
        </fieldset>
        '''

    The first parameter is the text for the fieldset legend. This text is context aware,
    so you can do things like::

        Fieldset("Data for {{ user.username }}",
            'form_field_1',
            'form_field_2'
        )
    """

    template = "%s/layout/fieldset.html"

    def __init__(self, legend, *fields, css_class=None, css_id=None, template=None, **kwargs):

        self.fields = list(fields)
        self.legend = legend
        self.css_class = css_class
        self.css_id = css_id
        self.template = template or self.template
        self.flat_attrs = flatatt(kwargs)

    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
        fields = self.get_rendered_fields(form, context, template_pack, **kwargs)

        legend = ""
        if self.legend:
            legend = "%s" % Template(str(self.legend)).render(context)

        template = self.get_template_name(template_pack)
        return render_to_string(template, {"fieldset": self, "legend": legend, "fields": fields}) class Layout(LayoutObject):
    """
    Form Layout. It is conformed by Layout objects: `Fieldset`, `Row`, `Column`, `MultiField`,
    `HTML`, `ButtonHolder`, `Button`, `Hidden`, `Reset`, `Submit` and fields. Form fields
    have to be strings.
    Layout objects `Fieldset`, `Row`, `Column`, `MultiField` and `ButtonHolder` can hold other
    Layout objects within. Though `ButtonHolder` should only hold `HTML` and BaseInput
    inherited classes: `Button`, `Hidden`, `Reset` and `Submit`.

    Example::

        helper.layout = Layout(
            Fieldset('Company data',
                'is_company'
            ),
            Fieldset(_('Contact details'),
                'email',
                Row('password1', 'password2'),
                'first_name',
                'last_name',
                HTML('<img src="/media/somepicture.jpg"/>'),
                'company'
            ),
            ButtonHolder(
                Submit('Save', 'Save', css_class='button white'),
            ),
        )
    """

    def __init__(self, *fields):
        self.fields = list(fields)

    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
        return self.get_rendered_fields(form, context, template_pack, **kwargs) class MultiField(LayoutObject):
    """MultiField container. Renders to a MultiField <div>"""

    template = "%s/layout/multifield.html"
    field_template = "%s/multifield.html"

    def __init__(self, label, *fields, **kwargs):
        self.fields = list(fields)
        self.label_html = label
        self.label_class = kwargs.pop("label_class", "blockLabel")
        self.css_class = kwargs.pop("css_class", "ctrlHolder")
        self.css_id = kwargs.pop("css_id", None)
        self.help_text = kwargs.pop("help_text", None)
        self.template = kwargs.pop("template", self.template)
        self.field_template = kwargs.pop("field_template", self.field_template)
        self.flat_attrs = flatatt(kwargs)

    def render(self, form, context, template_pack=TEMPLATE_PACK, **kwargs):
        # If a field within MultiField contains errors
        if context["form_show_errors"]:
            for field in map(lambda pointer: pointer[1], self.get_field_names()):
                if field in form.errors:
                    self.css_class += " error"

        field_template = self.field_template % template_pack
        fields_output = self.get_rendered_fields(
            form,
            context,
            template_pack,
            template=field_template,
            labelclass=self.label_class,
            layout_object=self,
            **kwargs,
        )

        template = self.get_template_name(template_pack)
        context.update({"multifield": self, "fields_output": fields_output})

        return render_to_string(template, context.flatten()) class Row(Div):
    """
    Layout object. It wraps fields in a ``<div>`` and the template adds the
    appropriate class to render the contents in a row. e.g. ``form-row`` when
    using the Bootstrap4 template pack.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Row('form_field_1', 'form_field_2', css_id='row-example')

    It is also possible to nest Layout Objects within a Row::

        Row(
            Div(
                Field('form_field', css_class='field-class'),
                css_class='div-class',
            ),
            Div('form_field_2', css_class='div-class'),
        )
    """

    template = "%s/layout/row.html" class Submit(BaseInput):
    """
    Used to create a Submit button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> submit = Submit('Search the Site', 'search this site')
    >>> submit.render("", "", Context())
    '<input type="submit" name="search-the-site" value="search this site" '
    'class="btn btn-primary" id="submit-id-search-the-site"/>'

    >>> submit = Submit('Search the Site', 'search this site', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> submit.render("", "", Context())
    '<input type="submit" name="search-the-site" value="search this site" '
    'class="btn btn-primary custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Submit('submit', 'Submit'))
    """

    input_type = "submit"

    def __init__(self, name, value, *, css_id=None, css_class=None, template=None, **kwargs):
        self.field_classes = "submit submitButton" if get_template_pack() == "uni_form" else "btn btn-primary"
        super().__init__(name=name, value=value, css_id=css_id, css_class=css_class, template=template, **kwargs) def render_crispy_form(form, helper=None, context=None):
    """
    Renders a form and returns its HTML output.

    This function wraps the template logic in a function easy to use in a Django view.
    """
    from crispy_forms.templatetags.crispy_forms_tags import CrispyFormNode

    if helper is not None:
        node = CrispyFormNode("form", "helper")
    else:
        node = CrispyFormNode("form", None)

    node_context = Context(context)
    node_context.update({"form": form, "helper": helper})

    return node.render(node_context) def advanced_layout():
def template_packs(request, settings):
def check_template_pack(node, template_pack): class AdvancedFileForm(forms.Form):
    file_field = forms.FileField(widget=forms.FileInput(attrs={"class": "my-custom-class"}))
    clearable_file = forms.FileField(
        widget=forms.ClearableFileInput(attrs={"class": "my-custom-class"}), required=False, initial=FakeFieldFile()
    ) class CheckboxesSampleForm(forms.Form):
    checkboxes = forms.MultipleChoiceField(
        choices=((1, "Option one"), (2, "Option two"), (3, "Option three")),
        initial=(1,),
        widget=forms.CheckboxSelectMultiple,
    )

    alphacheckboxes = forms.MultipleChoiceField(
        choices=(("option_one", "Option one"), ("option_two", "Option two"), ("option_three", "Option three")),
        initial=("option_two", "option_three"),
        widget=forms.CheckboxSelectMultiple,
    )

    numeric_multiple_checkboxes = forms.MultipleChoiceField(
        choices=((1, "Option one"), (2, "Option two"), (3, "Option three")),
        initial=(1, 2),
        widget=forms.CheckboxSelectMultiple,
    )

    inline_radios = forms.ChoiceField(
        choices=(
            ("option_one", "Option one"),
            ("option_two", "Option two"),
        ),
        widget=forms.RadioSelect,
        initial="option_two",
    ) class CrispyEmptyChoiceTestModel(models.Model):
    fruit = models.CharField(
        choices=[("apple", "Apple"), ("pear", "Pear")],
        null=True,
        blank=True,
        max_length=20,
    ) class CrispyTestModel(models.Model):
    email = models.CharField(max_length=20)
    password = models.CharField(max_length=20) class FileForm(forms.Form):
    file_field = forms.FileField(widget=forms.FileInput)
    clearable_file = forms.FileField(widget=forms.ClearableFileInput, required=False, initial=FakeFieldFile()) class SampleForm(forms.Form):
    is_company = forms.CharField(label="company", required=False, widget=forms.CheckboxInput())
    email = forms.EmailField(
        label="email", max_length=30, required=True, widget=forms.TextInput(), help_text="Insert your email"
    )
    password1 = forms.CharField(label="password", max_length=30, required=True, widget=forms.PasswordInput())
    password2 = forms.CharField(label="re-enter password", max_length=30, required=True, widget=forms.PasswordInput())
    first_name = forms.CharField(label="first name", max_length=5, required=True, widget=forms.TextInput())
    last_name = forms.CharField(label="last name", max_length=5, required=True, widget=forms.TextInput())
    datetime_field = forms.SplitDateTimeField(label="date time", widget=forms.SplitDateTimeWidget())

    def clean(self):
        super().clean()
        password1 = self.cleaned_data.get("password1", None)
        password2 = self.cleaned_data.get("password2", None)
        if not password1 and not password2 or password1 != password2:
            raise forms.ValidationError("Passwords dont match")

        return self.cleaned_data class SampleForm2(SampleForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self) class SampleForm3(forms.ModelForm):
    class Meta:
        model = CrispyTestModel
        fields = ["email", "password"]
        exclude = ["password"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self) class SampleForm4(forms.ModelForm):
    class Meta:
        """
        before Django1.6, one cannot use __all__ shortcut for fields
        without getting the following error:
        django.core.exceptions.FieldError: Unknown field(s) (a, l, _) specified for CrispyTestModel
        because obviously it casts the string to a set
        """

        model = CrispyTestModel
        fields = "__all__"  # eliminate RemovedInDjango18Warning class SampleForm5(forms.Form):
    choices = [
        (1, 1),
        (2, 2),
        (1000, 1000),
    ]
    checkbox_select_multiple = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=choices)
    radio_select = forms.ChoiceField(widget=forms.RadioSelect, choices=choices)
    pk = forms.IntegerField() class SampleForm6(forms.ModelForm):
    class Meta:
        """
        When allowing null=True in a model field,
        the corresponding field will have a choice
        for the empty value.

        When the form is initialized by an instance
        with initial value None, this choice should
        be selected.
        """

        model = CrispyEmptyChoiceTestModel
        fields = ["fruit"]
        widgets = {"fruit": forms.RadioSelect()} class SelectSampleForm(forms.Form):
    select = forms.ChoiceField(
        choices=((1, "Option one"), (2, "Option two"), (3, "Option three")), initial=(1,), widget=forms.Select
    )
import pytest
from django import forms
from django.forms.models import formset_factory, modelformset_factory
from django.middleware.csrf import _get_new_csrf_string
from django.shortcuts import render
from django.template import Context, Template
from django.test.html import parse_html
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from crispy_forms.bootstrap import Field, InlineCheckboxes, UneditableField
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, ButtonHolder, Column, Div, Fieldset, Layout, MultiField, Row, Submit
from crispy_forms.utils import render_crispy_form
from .conftest import only_bootstrap3, only_bootstrap4
from .forms import (
    AdvancedFileForm,
    CheckboxesSampleForm,
    CrispyEmptyChoiceTestModel,
    CrispyTestModel,
    FileForm,
    SampleForm,
    SampleForm2,
    SampleForm3,
    SampleForm4,
    SampleForm5,
    SampleForm6,
    SelectSampleForm,
)
from .utils import contains_partial, parse_expected, parse_form

def test_i18n():
    template = Template(
        """
        {% load crispy_forms_tags %}
        {% crispy form form.helper %}
    """
    )
    form = SampleForm()
    form_helper = FormHelper()
    form_helper.layout = Layout(
        HTML(_("i18n text")),
        Fieldset(
            _("i18n legend"),
            "first_name",
            "last_name",
        ),
    )
    form.helper = form_helper

    html = template.render(Context({"form": form}))
    assert html.count("i18n legend") == 1


def test_default_layout():
    test_form = SampleForm2()
    assert test_form.helper.layout.fields == [
        "is_company",
        "email",
        "password1",
        "password2",
        "first_name",
        "last_name",
        "datetime_field",
    ]


def test_default_layout_two():
    test_form = SampleForm3()
    assert test_form.helper.layout.fields == ["email"]


def test_modelform_layout_without_meta():
    test_form = SampleForm4()
    test_form.helper = FormHelper()
    test_form.helper.layout = Layout("email")
    html = render_crispy_form(test_form)

    assert "email" in html
    assert "password" not in html


def test_specialspaceless_not_screwing_intended_spaces():
    # see issue #250
    test_form = SampleForm()
    test_form.fields["email"].widget = forms.Textarea()
    test_form.helper = FormHelper()
    test_form.helper.layout = Layout("email", HTML("<span>first span</span> <span>second span</span>"))
    html = render_crispy_form(test_form)
    assert "<span>first span</span> <span>second span</span>" in html


def test_choice_with_none_is_selected():
    # see issue #701
    model_instance = CrispyEmptyChoiceTestModel()
    model_instance.fruit = None
    test_form = SampleForm6(instance=model_instance)
    html = render_crispy_form(test_form)
    assert "checked" in html


@only_bootstrap3
def test_layout_composition(settings):
    form_helper = FormHelper()
    form_helper.add_layout(
        Layout(
            Layout(
                MultiField(
                    "Some company data",
                    "is_company",
                    "email",
                    css_id="multifield_info",
                ),
            ),
            Column(
                "first_name",
                # 'last_name', Missing a field on purpose
                css_id="column_name",
                css_class="columns",
            ),
            ButtonHolder(
                Submit("Save", "Save", css_class="button white"),
            ),
            Div(
                "password1",
                "password2",
                css_id="custom-div",
                css_class="customdivs",
            ),
        )
    )

    template = Template(
        """
            {% load crispy_forms_tags %}
            {% crispy form form_helper %}
        """
    )
    c = Context({"form": SampleForm(), "form_helper": form_helper})
    html = template.render(c)

    # Bootstrap 4 does not contain a multifield template
    assert parse_html(html) == parse_expected("bootstrap3/test_layout/test_layout_composition.html")


@only_bootstrap3
def test_second_layout_multifield_column_buttonholder_submit_div(settings):
    form_helper = FormHelper()
    form_helper.add_layout(
        Layout(

            MultiField(