Definir la clase css en django Forms

Supongamos que tengo un formulario

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

¿Hay alguna manera de definir clases de css en cada campo para poder usar jQuery en función de la clase en mi página representada?

Esperaba no tener que construir manualmente el formulario.

Otra solución que no requiere cambios en el código de Python y, por lo tanto, es mejor para los diseñadores y para los cambios de presentación únicos : django-widget-tweaks . Espero que alguien lo encuentre útil.

Respondí mi propia pregunta. Suspiro

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

No me di cuenta de que se había pasado al constructor de widgets.

Aquí hay otra solución para agregar definiciones de clase a los widgets después de declarar los campos en la clase.

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

Use django-widget-tweaks , es fácil de usar y funciona bastante bien.

De lo contrario, esto se puede hacer usando un filtro de plantilla personalizado.

Teniendo en cuenta que representa su forma de esta manera:

 
{{ form.non_field_errors }}
{{ form.subject.errors }} {{ form.subject }}

form.subject es una instancia de BoundField que tiene el método as_widget .

puede crear un filtro personalizado “addcss” en “my_app / templatetags / myfilters.py”

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

Y luego aplique su filtro:

 {% load myfilters %} 
{{ form.non_field_errors }}
{{ form.subject.errors }} {{ form.subject|addcss:'MyClass' }}

Form.subjects se procesará con la clase css “MyClass”.

Espero que esto ayude.

EDITAR 1

  • Actualizar filtro de acuerdo a la respuesta de dimyG .

  • Añadir django-widget-tweak link

Editar 2

  • Actualizar filtro según el comentario de Bhyd .

Ampliando el método señalado en docs.djangoproject.com:

 class MyForm(forms.Form): comment = forms.CharField( widget=forms.TextInput(attrs={'size':'40'})) 

Pensé que era problemático tener que saber el tipo de widget nativo para cada campo, y me pareció gracioso anular el valor predeterminado solo para poner un nombre de clase en un campo de formulario. Esto parece funcionar para mí:

 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' 

Esto me parece un poco más limpio.

Si desea que todos los campos del formulario hereden una determinada clase, simplemente defina una clase primaria, que hereda de los forms.ModelForm , y luego hereda de ella

 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 

Esto me ayudó a agregar la clase 'form-control' a todos los campos en todos los formularios de mi aplicación automáticamente, sin agregar replicación de código.

Aquí está la manera simple de alterar a la vista. Agregue a continuación en la vista justo antes de pasarlo a la plantilla.

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

Simplemente agregue las clases a su formulario de la siguiente manera.

 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' } )) 

Aquí hay una variación de lo anterior que dará a todos los campos la misma clase (por ejemplo, esquinas redondeadas de jquery nice).

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

En caso de que desee agregar una clase al campo de un formulario en una plantilla (no en view.py o form.py), por ejemplo, en los casos en que quiera modificar aplicaciones de terceros sin anular sus vistas, entonces utilice un filtro de plantilla como se describe. En Charlesthk la respuesta es muy conveniente. Pero en esta respuesta, el filtro de plantilla anula cualquier clase existente que pueda tener el campo.

Intenté agregar esto como una edición, pero se sugirió que se escribiera como una nueva respuesta.

Entonces, aquí hay una etiqueta de plantilla que respeta las clases existentes del campo:

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

Puedes probar esto ..

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

Puedes ver más información en: Django Widgets.

Resulta que puedes hacer esto en el constructor de formularios (función init ) o después de que se haya iniciado la clase de formularios. Esto a veces es necesario si no está escribiendo su propio formulario y ese formulario proviene de otro lugar:

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

También puedes usar Django Crispy Forms , es una excelente herramienta para definir formularios en caso de que quieras usar algún marco de CSS como Bootstrap o Foundation. Y es fácil especificar las clases para los campos de formulario allí.

A tu clase de formulario le gustaría esto, entonces:

 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'), ) )