widgets tweaks formularios form bootstrap python django django-forms

python - tweaks - Definir clase css en django Forms



submit django form (12)

Asumir 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 utilizar jQuery en función de la clase en mi página representada?

Esperaba no tener que compilar manualmente el formulario.


Ampliando el método apuntado a docs.djangoproject.com:

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

Pensé que era problemático tener que conocer el tipo de widget nativo para cada campo, y me pareció divertido 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.


Aquí hay otra solución para agregar definiciones de clases 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''


Aquí hay una manera simple de alterar a la vista. agregue abajo a la vista justo antes de pasarlo a la plantilla.

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


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

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


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

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


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

Traté de 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})


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



Si desea que todos los campos del formulario hereden una determinada clase, solo debe definir una clase principal, que hereda de forms.ModelForm , y luego heredar 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 todas las formas de mi aplicación automáticamente, sin agregar replicación de código.


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


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

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


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

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

Teniendo en cuenta que rinde su forma de esta manera:

<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 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'', None).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 aplica tu filtro:

{% 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 se representará con la clase css "MyClass".

Espero que esto ayude.

EDITAR

  • Actualizar filtro según la respuesta de dimyG

  • Añadir el enlace django-widget-tweak