假设我有一个表格
class SampleClass(forms.Form):
name = forms.CharField(max_length=30)
age = forms.IntegerField()
django_hacker = forms.BooleanField(required=False)
有没有办法让我在每个字段上定义 css 类,以便我可以在渲染页面中使用基于类的 jQuery?
我希望不必手动构建表单。
假设我有一个表格
class SampleClass(forms.Form):
name = forms.CharField(max_length=30)
age = forms.IntegerField()
django_hacker = forms.BooleanField(required=False)
有没有办法让我在每个字段上定义 css 类,以便我可以在渲染页面中使用基于类的 jQuery?
我希望不必手动构建表单。
另一个不需要更改 python 代码的解决方案,因此更适合设计人员和一次性的演示更改:django-widget-tweaks。希望有人会发现它有用。
回答了我自己的问题。叹
http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs
我没有意识到它被传递到小部件构造函数中。
这是在类中声明字段后向小部件添加类定义的另一种解决方案。
def __init__(self, *args, **kwargs):
super(SampleClass, self).__init__(*args, **kwargs)
self.fields['name'].widget.attrs['class'] = 'my_class'
使用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
扩展指向 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'
这对我来说似乎更干净一些。
如果你想让表单中的所有字段都继承某个类,你只需定义一个父类,它继承自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'
类自动添加到我的应用程序的所有表单上的所有字段中,而无需添加代码复制。
只需将类添加到您的表单中,如下所示。
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'
}
))
这是改变视图的简单方法。在将其传递到模板之前在视图中添加以下内容。
form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}
你可以试试这个。。
class SampleClass(forms.Form):
name = forms.CharField(max_length=30)
name.widget.attrs.update({'class': 'your-class'})
...
您可以在以下位置查看更多信息:Django Widgets
这是上面的一个变体,它将为所有字段提供相同的类(例如 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'
如果您想将类添加到模板(不在 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})
事实证明,您可以在表单构造函数(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})
你也可以使用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'),
)
)
您可以在此处获取各种输入字段的样式选项
小部件是 Django 对 HTML 输入元素的表示。小部件处理 HTML 的呈现,以及从对应于小部件的 GET/POST 字典中提取数据。
email = forms.EmailField(label='Your email', widget=forms.EmailInput(attrs={'class': 'ui segment teal'}))