假设我有一张表格

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

是否有一种方法为我定义css类在每个字段,这样我就可以使用jQuery基于类在我渲染的页面?

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


当前回答

事实证明,你可以在表单构造函数(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})

其他回答

扩展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'

我觉得这样更干净了。

下面是上面的一个变种,它将给所有字段相同的类(例如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'

要在django中定义css类,只需在表单中使用小部件即可。

例子:

class ProcessForm(forms.ModelForm):  
    class Meta:  
        model = Processmachine 
        fields = ['machine_name', 'operation_no', 'process_uploadfile'] #https://docs.djangoproject.com/en/3.0/ref/forms/widgets/
        widgets = { 'machine_name': forms.TextInput(attrs={ 'class': 'form-control' }), 
            'operation_no': forms.TextInput(attrs={ 'class': 'form-control' }),
            'process_uploadfile': forms.ClearableFileInput(attrs={ 'class': 'form-control' }),
      }

在上面的表单中,我在attrs中使用了css类

如果你想在模板(不是view.py或form.py)的表单字段中添加一个类,比如你想在不覆盖第三方应用程序视图的情况下修改它们,那么在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})

使用django-widget-tweak,它很容易使用,而且工作得很好。

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

考虑到你这样渲染你的表单:

<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>

的形式。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>

的形式。然后,主题将被“MyClass”css类渲染。

希望这对你有所帮助。

编辑1

根据dimyG的答案更新过滤器 添加django-widget-tweak链接

编辑2

根据byhyd的评论更新过滤器