Django 窗体中的 CSS 样式

我想设计如下:

表格:

from django import forms


class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)

Contact _ form. html:

<form action="" method="post">
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>

例如,如何为 subjectemailmessage设置 同学们身份证以提供外部样式表?

235923 次浏览

摘自我对以下问题的回答: 如何在 Django 中用 < div class = & # 39; field _ type & # 39; > 标记表单字段

class MyForm(forms.Form):
myfield = forms.CharField(widget=forms.TextInput(attrs={'class': 'myfieldclass'}))

或者

class MyForm(forms.ModelForm):
class Meta:
model = MyModel


def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['myfield'].widget.attrs.update({'class': 'myfieldclass'})

或者

class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'myfield': forms.TextInput(attrs={'class': 'myfieldclass'}),
}

- 编辑
以上是对原始问题代码进行的最简单的更改,可以完成所提出的问题。如果在其他地方重用表单,它还可以防止您重复自己的操作; 如果使用 Django 的 as _ table/as _ ul/as _ p 表单方法,那么您的类或其他属性就可以正常工作。如果您需要完全控制一个完全自定义的渲染,这是 < a href = “ https://docs.djangoproject.com/en/4.1/subject/forms/# working-with-form-template”rel = “ nofollow noReferrer”> 清楚地记录

——编辑2——
添加了为 ModelForm 指定小部件和 attrs 的新方法。

你可以这样做:

class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
subject.widget.attrs.update({'id' : 'your_id'})

希望能管用。

伊格纳斯

你可以这样做:

<form action="" method="post">
<table>
{% for field in form %}
<tr><td>\{\{field}}</td></tr>
{% endfor %}
</table>
<input type="submit" value="Submit">
</form>

然后您可以将 class/id 添加到例如 <td>标记中。当然,您可以使用任何其他您想要的标记。以 使用 Django 表单为例,检查表单中每个 field可用的内容(例如,\{\{field}}只输出输入标记,而不是标签等等)。

您可能不需要覆盖表单类的 __init__,因为 Django 在 HTML input中设置 nameid属性。你可以像这样使用 CSS:

form input[name='subject'] {
font-size: xx-large;
}

如果您不想在表单中添加 任何代码(正如@hadfc 的答案的注释中所提到的) ,那么这当然是可能的,这里有两个选项。

首先,您只需在 HTML 中引用字段 单独谈,而不是同时引用整个表单:

<form action="" method="post">
<ul class="contactList">
<li id="subject" class="contact">\{\{ form.subject }}</li>
<li id="email" class="contact">\{\{ form.email }}</li>
<li id="message" class="contact">\{\{ form.message }}</li>
</ul>
<input type="submit" value="Submit">
</form>

(注意,我还将其更改为未排序的 名单。)

其次,姜戈,在 输出 HTML 格式的表单的文档中要注意:

字段 id 由 在字段名前面加上‘ id _’。 Id 属性和标记是 默认情况下包含在输出中。

所有表单字段都已经具有唯一的 身份证。因此,您可以在 CSS 文件中引用 主题来设置 主题字段的样式。我应该指出,这是表单在使用 违约 HTML 时的行为,它只需要打印表单,而不是单独的字段:

<ul class="contactList">
\{\{ form }}  # Will auto-generate HTML with id_subject, id_email, email_message
\{\{ form.as_ul }} # might also work, haven't tested
</ul>

在输出表单时(可以处理表格等) ,请参阅前面的链接了解其他选项。

注意: 我知道这和在每个元素中添加一个 同学们是不一样的(如果你在表单中添加了一个字段,你也需要更新 CSS)——但是在 CSS 中通过 身份证引用所有的字段非常简单,如下所示:

#id_subject, #id_email, #email_message
{color: red;}

您可以使用这个库: https://pypi.python.org/pypi/django-widget-tweaks

它允许你做以下事情:

{% load widget_tweaks %}
<!-- add 2 extra css classes to field element -->
\{\{ form.title|add_class:"css_class_1 css_class_2" }}

这可以通过使用自定义模板过滤器来完成:

<form action="/contact/" method="post">
\{\{ form.non_field_errors }}
<div class="fieldWrapper">
\{\{ form.subject.errors }}
\{\{ form.subject.label_tag }}
\{\{ form.subject }}
<span class="helptext">\{\{ form.subject.help_text }}</span>
</div>
</form>

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

您可以在 My _ app/templatetags/myfilters.py中创建自定义过滤器 addclass:

from django import template


register = template.Library()


@register.filter(name='addclass')
def addclass(value, arg):
return value.as_widget(attrs={'class': arg})

然后用你的过滤器:

{% load myfilters %}


<form action="/contact/" method="post">
\{\{ form.non_field_errors }}
<div class="fieldWrapper">
\{\{ form.subject.errors }}
\{\{ form.subject.label_tag }}
\{\{ form.subject|addclass:'MyClass' }}
<span class="helptext">\{\{ form.subject.help_text }}</span>
</div>
</form>

然后使用 MyClass CSS 类呈现 form.subjects

没看过这个..。

Https://docs.djangoproject.com/en/1.8/ref/forms/api/#more-granular-output

更多的颗粒输出

As _ p ()、 as _ ul ()和 as _ table ()方法只是懒惰开发人员的快捷方式——它们不是显示表单对象的唯一方式。

边界球场课程 用于显示 Form 实例的单个字段的 HTML 或访问属性。

此对象的 STR()(Python 2上的 Unicode)方法显示此字段的 HTML。

要检索一个单独的边界字段,请在窗体上使用字典查找语法,并使用字段名作为键:

>>> form = ContactForm()
>>> print(form['subject'])
<input id="id_subject" type="text" name="subject" maxlength="100" />

为了检索所有的边界域对象,迭代表单:

>>> form = ContactForm()
>>> for boundfield in form: print(boundfield)
<input id="id_subject" type="text" name="subject" maxlength="100" />
<input type="text" name="message" id="id_message" />
<input type="email" name="sender" id="id_sender" />
<input type="checkbox" name="cc_myself" id="id_cc_myself" />

特定于字段的输出符合表单对象的 auto _ id 设置:

>>> f = ContactForm(auto_id=False)
>>> print(f['message'])
<input type="text" name="message" />
>>> f = ContactForm(auto_id='id_%s')
>>> print(f['message'])
<input type="text" name="message" id="id_message" />

对于每篇 这个博客文章,您可以使用自定义模板过滤器将 css 类添加到字段中。

from django import template
register = template.Library()


@register.filter(name='addcss')
def addcss(field, css):
return field.as_widget(attrs={"class":css})

把这个放到你的应用程序的模板标签/文件夹中,现在你可以这样做了

\{\{field|addcss:"form-control"}}

在 Django 1.10(也可能是更早的版本)中,您可以按照如下方式进行操作。

型号:

class Todo(models.Model):
todo_name = models.CharField(max_length=200)
todo_description = models.CharField(max_length=200, default="")
todo_created = models.DateTimeField('date created')
todo_completed = models.BooleanField(default=False)


def __str__(self):
return self.todo_name

表格:

class TodoUpdateForm(forms.ModelForm):
class Meta:
model = Todo
exclude = ('todo_created','todo_completed')

模板:

<form action="" method="post">{% csrf_token %}
\{\{ form.non_field_errors }}
<div class="fieldWrapper">
\{\{ form.todo_name.errors }}
<label for="\{\{ form.name.id_for_label }}">Name:</label>
\{\{ form.todo_name }}
</div>
<div class="fieldWrapper">
\{\{ form.todo_description.errors }}
<label for="\{\{ form.todo_description.id_for_label }}">Description</label>
\{\{ form.todo_description }}
</div>
<input type="submit" value="Update" />
</form>

一种解决方案是在页面准备好之后使用 JavaScript 添加所需的 CSS 类。例如,使用 bootstrap 类(用于简洁的 jQuery)对 django 表单输出进行样式化:

<script type="text/javascript">
$(document).ready(function() {
$('#some_django_form_id').find("input[type='text'], select, textarea").each(function(index, element) {
$(element).addClass("form-control");
});
});
</script>

这样就避免了将样式细节与业务逻辑混合在一起的丑陋。

有一个非常容易安装和伟大的工具为 Django,我使用的样式,它可以用于每一个前端框架,如 Bootstrap,材质化,基础等。它被称为小部件调整文档: Widget Tweaks

  1. 您可以将它与 Django 的通用视图一起使用
  2. 或者用你自己的形式:

从姜戈进口表格

class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)

不使用默认值:

\{\{ form.as_p }} or \{\{ form.as_ul }}

您可以使用 render _ field 属性按照自己的方式进行编辑,该属性为您提供了一种更类似于 html 的样式,如下例所示:

翻译: 奇芳

{% load widget_tweaks %}


<div class="container">
<div class="col-md-4">
{% render_field form.subject class+="form-control myCSSclass" placeholder="Enter your subject here" %}
</div>
<div class="col-md-4">
{% render_field form.email type="email" class+="myCSSclassX myCSSclass2" %}
</div>
<div class="col-md-4">
{% render_field form.message class+="myCSSclass" rows="4" cols="6" placeholder=form.message.label %}
</div>
</div>

这个库使您有机会将前端和后端很好地分离开来

编辑: 我建议的另一种(稍微好一点的)方法在这里得到了回答: < a href = “ https://stackoverflow.com/questions/35926441/Django-form-input-field-styling”> Django form input field styling

以上所有的选择都很棒,只是觉得我应该加上这一个,因为它是不同的。

如果希望在表单上使用自定义样式、类等,可以在模板中创建与表单字段相匹配的 html 输入。例如,对于 CharField (缺省小部件是 TextInput) ,假设需要一个引导程序样式的文本输入。你会这样做:

<input type="text" class="form-control" name="form_field_name_here">

只要表单字段名与 html name属性匹配(小部件可能也需要匹配输入类型) ,Django 就会在运行 validateform.is_valid()

设计标签、错误消息和帮助文本等其他东西不需要太多的变通方法,因为您可以执行类似 form.field.error.as_text的操作,并按照自己的想法设计它们的样式。实际的字段是需要一些修改的字段。

我不知道这是否是最好的方式,或者我会推荐的方式,但这是一种方式,而且可能对某些人来说是正确的。

下面是样式表单的有用演练,它包含了 SO 中列出的大多数答案(比如在小部件上使用 attr 和小部件调整)。 Https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html

对小部件实例进行样式化

如果希望使一个小部件实例看起来与另一个不同,那么在小部件对象实例化并分配给表单字段时,需要指定额外的属性(或许还需要向 CSS 文件添加一些规则)。

Https://docs.djangoproject.com/en/2.2/ref/forms/widgets/

为此,在创建小部件时使用 Widget.attrs 参数:

class CommentForm(forms.Form):
name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
url = forms.URLField()
comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))

还可以在表单定义中修改小部件:

class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField()


name.widget.attrs.update({'class': 'special'})
comment.widget.attrs.update(size='40')

或者,如果字段没有直接在表单上声明(比如模型表单字段) ,可以使用 Form.fields 属性:

class CommentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['name'].widget.attrs.update({'class': 'special'})
self.fields['comment'].widget.attrs.update(size='40')

然后 Django 将在呈现的输出中包含额外的属性:

>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special" required></td></tr>
<tr><th>Url:</th><td><input type="url" name="url" required></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" size="40" required></td></tr>

把你的表格写成这样:

    class MyForm(forms.Form):
name = forms.CharField(widget=forms.TextInput(attr={'class':'name'}),label="Your Name")
message = forms.CharField(widget=forms.Textarea(attr={'class':'message'}), label="Your Message")

在 HTML 字段中执行以下操作:

{% for field in form %}
<div class="row">
<label for="\{\{ field.name}}">\{\{ field.label}}</label>\{\{ field }}
</div>
{% endfor %}

然后在 CSS 中写下如下内容:

.name{
/* you already have this class so create it's style form here */
}
.message{
/* you already have this class so create it's style form here */
}
label[for='message']{
/* style for label */
}

希望这个答案值得一试!注意,您必须已经编写了视图才能呈现包含表单的 HTML 文件。

我用这个解决方案来保持整个应用程序的一致性:

def bootstrap_django_fields(field_klass, css_class):
class Wrapper(field_klass):
def __init__(self, **kwargs):
super().__init__(**kwargs)


def widget_attrs(self, widget):
attrs = super().widget_attrs(widget)
if not widget.is_hidden:
attrs["class"] = css_class
return attrs


return Wrapper




MyAppCharField = bootstrap_django_fields(forms.CharField, "form-control")

这样就不必在表单的基础上定义 css 类,只需使用自定义表单字段即可。


在启动时重新定义 Django 的 forms类在技术上也是可行的,如下所示:

forms.CharField = bootstrap_django_fields(forms.CharField, "form-control")

然后你可以设置全局样式,甚至不在你的直接控制应用程序。这似乎相当粗略,所以我不知道我是否可以推荐这一点。

对于较大的形式,而不是写 CSS 分类的每一个字段,你可以这样

class UserRegistration(forms.ModelForm):
# list charfields


class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password', 'password2')


def __init__(self, *args, **kwargs):
super(UserRegistration, self).__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs['class'] = 'form-control'