204

假设我有一个表格

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)

有没有办法让我在每个字段上定义 css 类,以便我可以在渲染页面中使用基于类的 jQuery?

我希望不必手动构建表单。

4

14 回答 14

190

另一个不需要更改 python 代码的解决方案,因此更适合设计人员和一次性的演示更改:django-widget-tweaks。希望有人会发现它有用。

于 2011-01-13T01:56:34.787 回答
95

回答了我自己的问题。

http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs

我没有意识到它被传递到小部件构造函数中。

于 2008-12-30T18:20:28.533 回答
82

这是在类中声明字段后向小部件添加类定义的另一种解决方案。

def __init__(self, *args, **kwargs):
    super(SampleClass, self).__init__(*args, **kwargs)
    self.fields['name'].widget.attrs['class'] = 'my_class'
于 2008-12-30T18:32:11.100 回答
47

使用django-widget-tweaks,它易于使用且运行良好。

否则,这可以使用自定义模板过滤器来完成。

考虑到您以这种方式呈现表单:

<form action="/contact/" method="post">
    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="id_subject">Email subject:</label>
        {{ form.subject }}
    </div>
</form>

form.subject 是BoundField的一个实例,它具有as_widget方法。

您可以在“my_app/templatetags/myfilters.py”中创建自定义过滤器“addcss”

from django import template

register = template.Library()

@register.filter(name='addcss')
def addcss(value, arg):
    css_classes = value.field.widget.attrs.get('class', '').split(' ')
    if css_classes and arg not in css_classes:
        css_classes = '%s %s' % (css_classes, arg)
    return value.as_widget(attrs={'class': css_classes})

然后应用您的过滤器:

{% load myfilters %}
<form action="/contact/" method="post">
    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="id_subject">Email subject:</label>
        {{ form.subject|addcss:'MyClass' }}
    </div>
</form>

form.subjects 将使用“MyClass”css 类呈现。

希望这有帮助。

编辑 1

  • 根据dimyG的回答更新过滤器

  • 添加 django-widget-tweak 链接

编辑 2

  • 根据Bhyd的评论更新过滤器
于 2013-09-23T14:55:01.993 回答
33

扩展指向 docs.djangoproject.com 的方法:

class MyForm(forms.Form): 
    comment = forms.CharField(
            widget=forms.TextInput(attrs={'size':'40'}))

我认为必须知道每个字段的本机小部件类型很麻烦,并且认为覆盖默认值只是将类名放在表单字段上很有趣。这似乎对我有用:

class MyForm(forms.Form): 
    #This instantiates the field w/ the default widget
    comment = forms.CharField()

    #We only override the part we care about
    comment.widget.attrs['size'] = '40'

这对我来说似乎更干净一些。

于 2010-11-25T00:06:15.370 回答
33

如果你想让表单中的所有字段都继承某个类,你只需定义一个父类,它继承自forms.ModelForm,然后从它继承

class BaseForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BaseForm, self).__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'someClass'


class WhateverForm(BaseForm):
    class Meta:
        model = SomeModel

这帮助我将'form-control'类自动添加到我的应用程序的所有表单上的所有字段中,而无需添加代码复制。

于 2013-12-13T18:35:43.863 回答
20

只需将类添加到您的表单中,如下所示。

class UserLoginForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(
        attrs={
        'class':'form-control',
        'placeholder':'Username'
        }
    ))
    password = forms.CharField(widget=forms.PasswordInput(
        attrs={
        'class':'form-control',
        'placeholder':'Password'
        }
    ))
于 2017-08-13T02:27:26.987 回答
17

这是改变视图的简单方法。在将其传递到模板之前在视图中添加以下内容。

form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}
于 2011-01-12T10:42:45.900 回答
6

你可以试试这个。。

class SampleClass(forms.Form):
  name = forms.CharField(max_length=30)
  name.widget.attrs.update({'class': 'your-class'})
...

您可以在以下位置查看更多信息:Django Widgets

于 2018-10-24T03:19:03.377 回答
5

这是上面的一个变体,它将为所有字段提供相同的类(例如 jquery 漂亮的圆角)。

  # Simple way to assign css class to every field
  def __init__(self, *args, **kwargs):
    super(TranslatedPageForm, self).__init__(*args, **kwargs)
    for myField in self.fields:
      self.fields[myField].widget.attrs['class'] = 'ui-state-default ui-corner-all'
于 2010-03-04T07:38:15.777 回答
2

如果您想将类添加到模板(不在 view.py 或 form.py 中)中的表单字段,例如在您想修改 3rd 方应用程序而不覆盖其视图的情况下,则使用所述的模板过滤器在Charlesthk 回答很方便。但是在这个答案中,模板过滤器会覆盖该字段可能具有的任何现有类。

我尝试将此添加为编辑,但建议将其编写为新答案。

因此,这是一个尊重该字段现有类的模板标签:

from django import template

register = template.Library()


@register.filter(name='addclass')
def addclass(field, given_class):
    existing_classes = field.field.widget.attrs.get('class', None)
    if existing_classes:
        if existing_classes.find(given_class) == -1:
            # if the given class doesn't exist in the existing classes
            classes = existing_classes + ' ' + given_class
        else:
            classes = existing_classes
    else:
        classes = given_class
    return field.as_widget(attrs={"class": classes})
于 2016-12-13T19:37:15.637 回答
1

事实证明,您可以在表单构造函数(init函数)中或在表单类启动后执行此操作。如果您不编写自己的表单并且该表单来自其他地方,则有时需要这样做 -

def some_view(request):
    add_css_to_fields = ['list','of','fields']
    if request.method == 'POST':
        form = SomeForm(request.POST)
        if form.is_valid():
            return HttpResponseRedirect('/thanks/')
    else:
        form = SomeForm()

    for key in form.fields.keys():
        if key in add_css_to_fields:
            field = form.fields[key]
            css_addition = 'css_addition '
            css = field.widget.attrs.get('class', '')
            field.widget.attrs['class'] = css_addition + css_classes

    return render(request, 'template_name.html', {'form': form})
于 2015-03-05T09:44:53.053 回答
1

你也可以使用Django Crispy Forms,如果你想使用一些 CSS 框架,如 Bootstrap 或 Foundation,它是一个定义表单的好工具。在那里为您的表单字段指定类很容易。

你的表单类会这样:

from django import forms

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Submit, Field
from crispy_forms.bootstrap import FormActions

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)

    helper = FormHelper()
    helper.form_class = 'your-form-class'
    helper.layout = Layout(
        Field('name', css_class='name-class'),
        Field('age', css_class='age-class'),
        Field('django_hacker', css-class='hacker-class'),
        FormActions(
            Submit('save_changes', 'Save changes'),
        )
    )
于 2016-12-21T17:09:26.637 回答
1

您可以在此处获取各种输入字段的样式选项

小部件是 Django 对 HTML 输入元素的表示。小部件处理 HTML 的呈现,以及从对应于小部件的 GET/POST 字典中提取数据。

email = forms.EmailField(label='Your email', widget=forms.EmailInput(attrs={'class': 'ui segment teal'}))
于 2021-08-10T18:42:39.617 回答