Solución:
Tomado de mi respuesta a: Cómo marcar campos de formulario con
class MyForm(forms.Form):
myfield = forms.CharField(widget=forms.TextInput(attrs={'class' : 'myfieldclass'}))
o
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'})
o
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'myfield': forms.TextInput(attrs={'class': 'myfieldclass'}),
}
— EDITAR —
El anterior es el cambio más fácil de realizar en el código de la pregunta original que cumple con lo que se preguntó. También evita que se repita si reutiliza el formulario en otros lugares; sus clases u otros atributos simplemente funcionan si usa los métodos de formulario as_table / as_ul / as_p de Django. Si necesita un control total para una representación completamente personalizada, esto está claramente documentado
– EDITAR 2 —
Se agregó una forma más nueva de especificar widgets y atributos para un ModelForm.
Esto se puede hacer usando un filtro de plantilla personalizado. Considere renderizar su formulario de esta manera:
<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
es una instancia de BoundField
que tiene el as_widget()
método.
Puedes crear un filtro personalizado addclass
en my_app / templatetags / myfilters.py:
from django import template
register = template.Library()
@register.filter(name="addclass")
def addclass(value, arg):
return value.as_widget(attrs={'class': arg})
Y luego aplica tu filtro:
{% 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>
form.subjects
luego se renderizará con el MyClass
Clase CSS.
Si no quieres agregar alguna código al formulario (como se menciona en los comentarios a la respuesta de @ shadfc), ciertamente es posible, aquí hay dos opciones.
Primero, solo hace referencia a los campos individualmente en el HTML, en lugar de todo el formulario a la vez:
<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>
(Tenga en cuenta que también lo cambié a un lista.)
En segundo lugar, tenga en cuenta en los documentos sobre la salida de formularios como HTML, Django:
La identificación del campo se genera anteponiendo ‘id_’ al nombre del campo. Los atributos de identificación y las etiquetas se incluyen en la salida de forma predeterminada.
Todos los campos de su formulario ya tienen un identificación. Entonces harías referencia id_subject en su archivo CSS para diseñar el tema campo. Debo señalar que así es como se comporta el formulario cuando se toma el defecto HTML, que solo requiere imprimir el formulario, no los campos individuales:
<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>
Consulte el enlace anterior para ver otras opciones al generar formularios (puede hacer tablas, etc.).
Nota: me doy cuenta de que esto no es lo mismo que agregar un clase a cada elemento (si agregó un campo al formulario, necesitaría actualizar el CSS también), pero es bastante fácil hacer referencia a todos los campos por identificación en tu CSS así:
#id_subject, #id_email, #email_message
{color: red;}