将类添加到表单字段Django ModelForm

Jos*_*uis 20 django django-templates django-forms

我正在尝试用Django ModelForm编写一个Bootstrap表单.我已经阅读了关于Forms的Django Documentation Django文档,所以我有这个代码:

<div class="form-group">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}</div>
Run Code Online (Sandbox Code Playgroud)

{{form.subject}}通过Django的呈现,例如,在CharField场模型,作为输入标签,

<input type="text"....> etc.
Run Code Online (Sandbox Code Playgroud)

我需要为每个输入添加"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'}))
Run Code Online (Sandbox Code Playgroud)

等等 ..

提前致谢.

Chr*_*ott 38

如果您不能使用第三方应用程序并希望以干燥的方式向表单中的每个字段添加一个类(例如,"表单控件"),则可以在表单类__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'
Run Code Online (Sandbox Code Playgroud)

您可能还需要在attrs中处理现有类的检查,如果由于某种原因您将在声明内部添加类__init__().上面的代码没有考虑到这种情况.

值得一提:

您指定不想使用第三方软件包.但是,我需要一秒钟的时间来提一下,自动制作表单渲染风格的最简单方法之一是使用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 %}
Run Code Online (Sandbox Code Playgroud)


Tom*_*dla 10

由于我花了比我想要的更多时间(django新手)来解决这个问题,我也将我的结果放在这里。

将小部件设置到每个字段只是为了一遍又一遍地添加一个类是违反重复的编程规则并导致许多不必要的行。在使用引导程序表单时尤其会发生这种情况。

这是我的(工作)示例,不仅用于添加引导程序类:

表格.py

class CompanyForm(forms.Form):
    name = forms.CharField(label='Jméno')
    shortcut = forms.CharField(label='Zkratka')
    webpage = forms.URLField(label='Webové stránky')
    logo = forms.FileField(label='Logo')
Run Code Online (Sandbox Code Playgroud)

模板标签/custom_tags.py

from django import template
from django.urls import reverse

register = template.Library()

@register.filter('input_type')
def input_type(ob):
    '''
    Extract form field type
    :param ob: form field
    :return: string of form field widget type
    '''
    return ob.field.widget.__class__.__name__


@register.filter(name='add_classes')
def add_classes(value, arg):
    '''
    Add provided classes to form field
    :param value: form field
    :param arg: string of classes seperated by ' '
    :return: edited field
    '''
    css_classes = value.field.widget.attrs.get('class', '')
    # check if class is set or empty and split its content to list (or init list)
    if css_classes:
        css_classes = css_classes.split(' ')
    else:
        css_classes = []
    # prepare new classes to list
    args = arg.split(' ')
    for a in args:
        if a not in css_classes:
            css_classes.append(a)
    # join back to single string
    return value.as_widget(attrs={'class': ' '.join(css_classes)})
Run Code Online (Sandbox Code Playgroud)

reusable_form_fields.html(模板)

{% load custom_tags %}

{% csrf_token %}
{% for field in form %}
    <div class="form-group row">
        {% if field|input_type == 'TextInput' %}
            <div for="{{ field.label }}" class="col-sm-2 col-form-label">
                {{ field.label_tag }}
            </div>
            <div class="col-sm-10">
                {{ field|add_classes:'form-control'}}
                {% if field.help_text %}
                    <small class="form-text text-muted">{{ field.help_text }}</small>
                {% endif %}
            </div>
        {% else %}
            ...
        {% endif %}
    </div>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)


Sau*_*tel 5

您可以在Forms.py中添加CSS类

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


Ari*_*ury 5

脆皮形式是要走的路。Bootstrap 的提示 4. 添加到@Christian Abbott 的答案中,对于表单,bootstrap 说,使用 form-group 和 form-control 。这就是它对我的工作方式。

我的表格.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'),
    )
Run Code Online (Sandbox Code Playgroud)

我的 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 %}
Run Code Online (Sandbox Code Playgroud)

注意:如果您对模型字段使用 CK Editor RichTextField(),则该字段不会受到影响。如果有人知道,请更新此内容。