Question

I'm trying to use the Bootstrap package with django-crispy-forms on an existing project.

I have ~15 forms in which I'd like to have these classes:

label_class = 'col-sm-3'
input_class = 'col-sm-9'

Is there a way to specify these defaults on settings or somewhere else without having to update all my forms ?


Also, I was previously using django-bootstrap-form where I was specifying the classes from the templates:

{{ my_form|bootstrap_horizontal:'col-sm-3' }}

I find more logical to control the rendering from the template rather than from the form definition. A form can be used in several pages without having the same rendering

Was it helpful?

Solution

Not sure it's very pretty but I didn't find any simpler solution yet, so here is what I did:

As I'd like to avoid updating all my forms, I'm going to define a standalone helper.

my_helpers.py

from crispy_forms.helper import FormHelper

class MyColFormHelper(FormHelper):
    label_class = 'col-sm-3'
    field_class = 'col-sm-9'
    form_tag = False
    disable_csrf = True

As I'd neither like to have to update all my views, I'm defining a context processor injecting the helper(s)

my_context_processors.py

from my_app.my_helpers import *

def form_helpers(request):
    return {
        'col_form': MyColFormHelper()
    }

Now I can simply specify the helper directly from the template

<form action="my_action" method="my_method">{% csrf_token %}
    {% crispy my_form col_form %}
</form>

This also allows me to use the same form in different locations and layouts.

This doesn't exactly answer to the question "default classes" but eased me the deployment of helpers.

The thing that I don't like much is that helpers are injected even if we don't need them.
So feel free to suggest any improvement.

OTHER TIPS

Django-crispy-forms also provides an option for Bootstrap 3 Horizontal forms: http://django-crispy-forms.readthedocs.org/en/latest/crispy_tag_forms.html#bootstrap3-horizontal-forms

You will only need to add the 3 attributes (form_class, label_class, field_class) to the form helper instead of adding them to each form field:

helper.form_class = 'form-horizontal'
helper.label_class = 'col-lg-2'
helper.field_class = 'col-lg-8'
helper.layout = Layout(
    'email',
    'password',
    'remember_me',
    StrictButton('Sign in', css_class='btn-default'),
)

From docs:

The way you do horizontal forms in Bootstrap version 3 is setting some col-lg-X classes in labels and divs wrapping fields. This would mean a lot of hassle updating your layout objects for settings these classes, too much verbosity. Instead some FormHelper attributes have been added to help you easily achieve this. You will need to set only three attributes.

Update: For multiple forms

For multiple forms I do this:

from crispy_forms.helper import FormHelper


def horizontal_helper(form):
    """ Adds the horizontal form classes
    to the given form"""
    form.helper = FormHelper(form)
    form.helper.form_class = 'form-horizontal'
    form.helper.label_class = 'col-md-2'
    form.helper.field_class = 'col-md-6'


class SomeForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(SomeForm, self).__init__(*args, **kwargs)
        horizontal_helper(self)
        ...


class AnotherForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(AnotherForm, self).__init__(*args, **kwargs)
        horizontal_helper(self)
        ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top