Добавить класс в поле формы Django ModelForm

Я пытаюсь написать форму начальной загрузки с Django ModelForm. Я прочитал документацию Django Документация Django о формах, поэтому у меня есть этот код:

<div class="form-group">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}</div>

{{form.subject}} отображается Django, например, в полевой модели CharField, как входной тег

<input type="text"....> etc.

Мне нужно добавить класс "form-control" к каждому входу, чтобы получить внешний вид входа Bootstrap (без сторонних пакетов). Я нашел это решение Django добавить класс в поле формы. Есть ли способ добавить класс в каждое поле по умолчанию, не указывая его в каждом атрибуте класса класса Form?

class ExampleForm(forms.Form):
   name = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}))
   email = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}))
   address = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}))
   country = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}))

и так далее..

Заранее спасибо.

Ответ 1

Если вы не можете использовать стороннее приложение и хотите добавить класс (например, "управление формой") к каждому полю в форме в СУХОЙ манере, вы можете сделать это в методе класса формы __init__(), например так:

class ExampleForm(forms.Form):
    # Your declared form fields here
    ...

    def __init__(self, *args, **kwargs):
        super(ExampleForm, self).__init__(*args, **kwargs)
        for visible in self.visible_fields():
            visible.field.widget.attrs['class'] = 'form-control'

Возможно, вам также потребуется выполнить проверку существующих классов в attrs, если по какой-то причине вы будете добавлять классы как декларативно, так и внутри __init__(). Приведенный выше код не учитывает этот случай.

Стоит упомянуть:

Вы указали, что не хотите использовать сторонние пакеты. Однако я потрачу одну секунду, чтобы упомянуть, что одним из самых простых способов автоматического создания форм в стиле Bootstrap является использование django-crispy-forms, например:

# settings.py
CRISPY_TEMPLATE_PACK = 'bootstrap3'

# forms.py
from crispy_forms.helper import FormHelper
class ExampleForm(forms.Form):
    # Your declared form fields here
    ...
    helper = FormHelper()

# In your template, this renders the form Bootstrap-style:
{% load crispy_forms_tags %}
{% crispy form %}

Ответ 2

Вы можете добавить CSS-классы в forms.py

subject = forms.CharField(label='subject', max_length=100 , widget=forms.TextInput(attrs={'class': "form-control"}))

Ответ 3

Хрустящие формы - путь. Советы по Bootstrap 4. В ответ на @Christian Abbott добавьте ответ. Для форм, как говорит самозагрузчик, используйте form-group и form-control. Вот как это работает для меня.

Мои forms.py

class BlogPostForm(forms.ModelForm):
    class Meta:
        model = models.Post
        fields = ['title', 'text', 'tags', 'author', 'slug']
    helper = FormHelper()
    helper.form_class = 'form-group'
    helper.layout = Layout(
        Field('title', css_class='form-control mt-2 mb-3'),
        Field('text', rows="3", css_class='form-control mb-3'),
        Field('author', css_class='form-control mb-3'),
        Field('tags', css_class='form-control mb-3'),
        Field('slug', css_class='form-control'),
    )

Мой post_create.html

{% extends 'blog/new_blog_base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">

<form method='POST' enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.media }}
    {% crispy form %}

<hr>
<input type="submit" name="Save" value="Save" class='btn btn-primary'> <a href="{% url 'home' %}" class='btn btn-danger'>Cancel</a>
</form>

</div>
{% endblock %}

Примечание. Если вы используете CK Editor RichTextField() для поля модели, это поле не будет затронуто. Если кто-то знает об этом, обновите это.

Ответ 4

Один из способов - создать базовый класс формы и вручную обновить атрибут поля внутри метода __init__.

Другим является использование уже существующих библиотек, таких как: https://github.com/dyve/django-bootstrap3

В github есть много таких библиотек. Осмотритесь.

Ответ 5

Я знаю, что автор спрашивал о Bootstrap для собственной формы, но есть дополнительный способ включить тег класса Bootstrap в форму Django для аутентификации, сброса пароля и т.д.

Если мы создадим шаблон со стандартной формой:

<form action="" method="post">
   {% csrf_token %}
   {{ form }}
</form>

затем в исходном коде браузера мы видим все поля формы с тегами:

<form action="" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="xxx">
    <tr><th><label for="id_old_password">Old password:</label></th><td><input type="password" name="old_password" autofocus required id="id_old_password"></td></tr>
    <tr><th><label for="id_new_password1">New password:</label></th><td><input type="password" name="new_password1" required id="id_new_password1"></td></tr>
    <tr><th><label for="id_new_password2">New password confirmation:</label></th><td><input type="password" name="new_password2" required id="id_new_password2"></td></tr>
</form>

Переменная {{ form }} в нашем шаблоне теперь может быть заменена этим кодом и необходимыми нам классами Bootstrap:

<div class="fieldWrapper form-group" aria-required="true">
    <label for="id_old_password">Old password:</label><span class="required">*</span>
    <input type="password" **class="form-control"** name="old_password" autofocus required id="id_old_password">
</div>

Может быть, это может быть полезно для перепроектирования встроенных статических форм.