在django Forms中定义css类

ash*_*her 181 python django django-forms

假设我有一个表格

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)
Run Code Online (Sandbox Code Playgroud)

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

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

Mik*_*bov 178

另一个不需要更改python代码的解决方案因此更适合设计人员和一次性表示性更改:django-widget-tweaks.希望有人会觉得它很有用.

  • 我必须说,**只有**理智的解决方案.谢谢!.Python代码,特别是在表单的定义中,是最后放置样式的东西 - 这些绝对属于模板. (56认同)
  • 这是一个很棒的图书馆!遗憾的是,这个答案被埋没在底部. (4认同)
  • django-widget-tweaks 是一个为期一年左右的爵士乐队项目,任何人都可以提供帮助 - 加入 jazzband 组织,并且您拥有 django-widget-tweaks 的提交权利。jazzband org 被允许发布 pypi 版本。所以如果有人想帮忙,他/她甚至不需要我。让我们看看它是如何工作的:) 看起来人们正在使用这个包并且认为它很好,但是没有人采取措施来维护它。它需要维护者。封装非常简单:不到200行代码,其中只有30行左右是核心逻辑。90%+ 测试覆盖率。如果您觉得有用请帮忙。 (2认同)

ash*_*her 87

回答了我自己的问题.

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

我没有意识到它被传递给widget构造函数.

  • 这是否意味着它不能与ModelForm类一起使用? (2认同)
  • 不,您只需要在模型表单中显式定义表单字段,这样您就可以定义小部件。或者使用下面列出的解决方案来避免必须弄乱表单字段。 (2认同)

ash*_*her 74

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

def __init__(self, *args, **kwargs):
    super(SampleClass, self).__init__(*args, **kwargs)
    self.fields['name'].widget.attrs['class'] = 'my_class'
Run Code Online (Sandbox Code Playgroud)

  • 对于ModelForms,这通常更好,因为您不需要知道正在使用的默认表单字段,并且您可以根据运行时条件动态设置不同的类.清洁比元编码黑客... (4认同)

Cha*_*thk 42

使用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>
Run Code Online (Sandbox Code Playgroud)

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

然后应用您的过滤器:

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

然后使用"MyClass"css类呈现form.subjects.

希望这有帮助.

编辑1

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

  • 添加django-widget-tweak链接

编辑2

  • 根据Bhyd的评论更新过滤器

  • 这很棒!它是DRY,它将显示层与控制层分开.来自我的+1! (3认同)

Dav*_*ave 32

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

class MyForm(forms.Form): 
    comment = forms.CharField(
            widget=forms.TextInput(attrs={'size':'40'}))
Run Code Online (Sandbox Code Playgroud)

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

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'
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎有点清洁.

  • @Chris Morgan实际上,他是第一个建议在Form声明本身中使用"comment.widget.attrs"(而不是在视图中搞乱__init__). (3认同)

Ole*_*sov 28

如果您希望表单中的所有字段都继承某个类,那么您只需定义一个继承自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
Run Code Online (Sandbox Code Playgroud)

这有助于我自动将'form-control'类添加到应用程序的所有形式的所有字段中,而无需添加代码复制.


Spi*_*man 15

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

form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}
Run Code Online (Sandbox Code Playgroud)


pau*_*ulc 14

只需将类添加到表单中,如下所示.

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


小智 6

你可以试试这个..

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

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


小智 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'
Run Code Online (Sandbox Code Playgroud)