2008-09-21 11 views
47

¿Cómo puedo cambiar el ancho de un elemento de formulario textarea si utilicé ModelForm para crearlo?Cambiar el ancho de los elementos de formulario creados con ModelForm en Django

Aquí es mi clase de productos:

class ProductForm(ModelForm): 
    long_desc = forms.CharField(widget=forms.Textarea) 
    short_desc = forms.CharField(widget=forms.Textarea) 
    class Meta: 
     model = Product 

Y el código de la plantilla ...

{% for f in form %} 
    {{ f.name }}:{{ f }} 
{% endfor %} 

f es el elemento de forma real ...

Respuesta

100

La forma más fácil para su caso de uso es usar CSS. Es un lenguaje destinado a definir la presentación. Mire el código generado por el formulario, tome nota de los identificadores para los campos que le interesan y cambie la apariencia de estos campos a través de CSS.

Ejemplo para long_desc campo en su ProductForm (cuando el formulario no tiene un prefijo personalizado):

#id_long_desc { 
    width: 300px; 
    height: 200px; 
} 

segundo enfoque es pasar la palabra clave attrs a su constructor de widgets.

class ProductForm(ModelForm): 
    long_desc = forms.CharField(widget=forms.Textarea(attrs={'cols': 10, 'rows': 20})) 
    short_desc = forms.CharField(widget=forms.Textarea) 
    class Meta: 
     model = Product 

Es described in Django documentation.

El tercer enfoque es dejar la agradable interfaz declarativa de newforms por un tiempo y establecer los atributos del widget en el constructor personalizado.

class ProductForm(ModelForm): 
    long_desc = forms.CharField(widget=forms.Textarea) 
    short_desc = forms.CharField(widget=forms.Textarea) 
    class Meta: 
     model = Product 

    # Edit by bryan 
    def __init__(self, *args, **kwargs): 
     super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor 
     self.fields['long_desc'].widget.attrs['cols'] = 10 
     self.fields['long_desc'].widget.attrs['rows'] = 20 

Este enfoque tiene las siguientes ventajas:

  • Puede definir widget de atributos para los campos que se generan automáticamente a partir de su modelo sin redefinir campos enteros.
  • No depende del prefijo de su formulario.
+0

El segundo funcionaba perfectamente –

+2

Opción 3 es muy útil. Quizás el ejemplo también podría mostrar que los campos no necesitan definirse en el Formulario, pero aún pueden anular los campos definidos en el Modelo que se procesan automáticamente. –

15

Excelente respuesta de zuber, pero creo que hay un error en el código de ejemplo para el tercer enfoque. El constructor debe ser:

def __init__(self, *args, **kwargs): 
    super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor 
    self.fields['long_desc'].widget.attrs['cols'] = 10 
    self.fields['long_desc'].widget.attrs['cols'] = 20 

Los objetos Field no tienen atributos 'attrs', pero sí sus widgets.

+1

Eso realmente debería ser una edición, en lugar de su propia respuesta (es mejor con el modelo SO), pero no tiene la reputación suficiente para realizar ediciones ... –

+1

He fusionado la edición, podemos mantener esta respuesta también si alguien quiere votarlo. –

+2

Lo siento, tienes razón, debería haber dejado un comentario en su lugar. Lo haré mejor la próxima vez :) – bryan

4

En caso de que esté utilizando un complemento como Grappelli que hace un uso intensivo de los estilos, es posible que los atributos de fila y col anulados se ignoren debido a los selectores de CSS que actúan en su widget. Esto podría ocurrir cuando se utiliza el excelente segundo o tercer enfoque de zuber anterior.

En este caso, simplemente use el Primer Enfoque combinado con el Segundo o Tercer Enfoque estableciendo un atributo 'estilo' en lugar de los atributos 'filas' y 'cols'.

He aquí un ejemplo modificando init en el tercer enfoque anterior:

def __init__(self, *args, **kwargs): 
    super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor 
    self.fields['short_desc'].widget.attrs['style'] = 'width:400px; height:40px;' 
    self.fields['long_desc'].widget.attrs['style'] = 'width:800px; height:80px;' 
+0

También puede agregar clases css en el admin.py para el ModelAdmin, creo que será un poco más limpio. Un poco decepcionado de que Grappelli no use los cols/rows que proporciona el stock django admin. – radtek

0

Conjunto fila y su clase CSS en la vista administrador modelo:

'explicacion': AutosizedTextarea(attrs={'rows': 5, 'class': 'input-xxlarge', 'style': 'width: 99% !important; resize: vertical !important;'}), 
Cuestiones relacionadas