Bootstrap3 inline forms in django-crispy-forms not

2019-04-23 11:17发布

问题:

I am using django-crispy-forms to render a Bootstrap3 inline form (code shown below), but the errors upon form submission (like skipping required fields) are not being shown. They do in normal and horizontal form layouts.

Could someone please suggest the possible reason(s)?

Models.py

class Person(models.Model):
    name = models.CharField(max_length=500)
    city = models.CharField(max_length=50)
    country = models.CharField(max_length=50)
    email = models.EmailField(blank=True)

Forms.py

class EntryForm(forms.ModelForm):
    class Meta:
        model = Person

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

        self.helper = FormHelper(self)
        self.helper.form_class = 'form-inline'
        self.helper.field_template = 'bootstrap3/layout/inline_field.html'
        self.helper.layout.append(ButtonHolder(
            Submit('save', 'Save', css_class='btn-primary btn-hg')
            )
        )

I am using {% load crispy_forms_tags %} and {% crispy form %} in my template.

回答1:

The reason is that the inline_field.html template that you use, doesn't have a code to display errors.

Please compare normal bootstrap3/field.html to the inline version. You will notice that the

{% include 'bootstrap3/layout/help_text_and_errors.html' %}

is missing in the latter. After you change the inline to something like below you'll have error messages back.

{% load crispy_forms_field %}

{% if field.is_hidden %}
    {{ field }}
{% else %}
    {% if field|is_checkbox %}
        <div id="div_{{ field.auto_id }}" class="checkbox">
           <label for="{{ field.id_for_label }}" class="{% if field.field.required %} requiredField{% endif %}">
                {% crispy_field field 'class' 'checkbox' %}
                {{ field.label|safe }}
                {% include 'bootstrap3/layout/help_text_and_errors.html' %}
            </label>
        </div>
    {% else %}
        <div id="div_{{ field.auto_id }}" class="form-group">
            <label for="{{ field.id_for_label }}" class="sr-only{% if field.field.required %} requiredField{% endif %}">
                {{ field.label|safe }}
            </label>
            {% crispy_field field 'placeholder' field.label %}
            {% include 'bootstrap3/layout/help_text_and_errors.html' %}
        </div>
    {% endif %}
{% endif %}

Of course error messages are quite ugly (as they come from normal version) so you probably have to create inline version of the bootstrap3/layout/help_text_and_errors.html. Also some error css classes might be needed - see the field.html.



回答2:

Below is the current configuration for my projects. I think it might work for you too.

#forms.py
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, Div
from crispy_forms.bootstrap import  FormActions
from myapp.models import Person

class EntryForm(forms.ModelForm):
    class Meta:
        model = Person

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

        self.helper = FormHelper()
        self.helper.form_id = 'id-entryform'
        self.helper.form_class = 'form-inline'
        self.helper.form.method = 'post'
        self.helper.form.action = ''
        self.helper.layout = Layout(
            Div('name','email'),
            Div('country','city'),
            FormActions(Submit('save', 'Save', css_class='btn-primary btn-hg')
            )
        )