将类添加到表单字段Django ModelForm

时间:2022-02-05 19:18:50

I am trying to write a Bootstrap Form with Django ModelForm. I have read the Django Documentation Django Documentation about Forms, so I have this code:

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

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

The {{form.subject}} is rendered by Django, for example in CharField field model, as input tag,

{{form.subject}}由Django呈现,例如在CharField字段模型中,作为输入标记,

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

I need add "form-control" class to every input in order to get Bootstrap input appearance (without third-party packages). I found this solution Django add class to form field. Is there any way to add a class to every field by default without specifying it in every attribute of the class of Form class?

我需要为每个输入添加“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'}))

and so on ..

等等 ..

Thanks in advance.

提前致谢。

4 个解决方案

#1


17  

If you can't use a third-party app and want to add a class (e.g., "form-control") to every field in a form in a DRY manner, you can do so in the form class __init__() method like so:

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

You might need to handle checking for existing classes in attrs too, if for some reason you'll be adding classes both declaratively and within __init__(). The above code doesn't account for that case.

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

Worth mentioning:

值得一提:

You specified that you don't want to use third-party packages. However, I'll take one second to mention that one of the simplest ways of automatically making forms render in the style of Bootstrap is to use django-crispy-forms, like this:

您指定不想使用第三方软件包。但是,我会花一秒钟提一下,以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


0  

One way is to create base form class and manually update the field's attribute inside __init__ method.

一种方法是创建基本表单类并手动更新__init__方法中的字段属性。

Another is by using already existing libraries like this one: https://github.com/dyve/django-bootstrap3

另一个是使用像这样的现有库:https://github.com/dyve/django-bootstrap3

There are plenty of these libraries around github. Look around.

github周围有很多这样的库。环视四周。

#3


0  

you can add CSS classes in forms.py

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

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

#4


0  

Crispy forms are the way to go . Tips for Bootstrap 4. Adding to @Christian Abbott's answer, For forms , bootstrap says, use form-group and form-control . This is how it worked for me .

脆皮形式是要走的路。 Bootstrap的提示4.添加到@Christian Abbott的答案,对于表单,bootstrap说,使用表单组和表单控件。这就是它对我有用的方式。

My forms.py

我的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'),
    )

My post_create.html

我的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 %}

Note : If you are using CK Editor RichTextField() for your model field , then that field wont be affected . If anyone knows about it , do update this .

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

#1


17  

If you can't use a third-party app and want to add a class (e.g., "form-control") to every field in a form in a DRY manner, you can do so in the form class __init__() method like so:

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

You might need to handle checking for existing classes in attrs too, if for some reason you'll be adding classes both declaratively and within __init__(). The above code doesn't account for that case.

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

Worth mentioning:

值得一提:

You specified that you don't want to use third-party packages. However, I'll take one second to mention that one of the simplest ways of automatically making forms render in the style of Bootstrap is to use django-crispy-forms, like this:

您指定不想使用第三方软件包。但是,我会花一秒钟提一下,以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


0  

One way is to create base form class and manually update the field's attribute inside __init__ method.

一种方法是创建基本表单类并手动更新__init__方法中的字段属性。

Another is by using already existing libraries like this one: https://github.com/dyve/django-bootstrap3

另一个是使用像这样的现有库:https://github.com/dyve/django-bootstrap3

There are plenty of these libraries around github. Look around.

github周围有很多这样的库。环视四周。

#3


0  

you can add CSS classes in forms.py

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

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

#4


0  

Crispy forms are the way to go . Tips for Bootstrap 4. Adding to @Christian Abbott's answer, For forms , bootstrap says, use form-group and form-control . This is how it worked for me .

脆皮形式是要走的路。 Bootstrap的提示4.添加到@Christian Abbott的答案,对于表单,bootstrap说,使用表单组和表单控件。这就是它对我有用的方式。

My forms.py

我的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'),
    )

My post_create.html

我的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 %}

Note : If you are using CK Editor RichTextField() for your model field , then that field wont be affected . If anyone knows about it , do update this .

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