Change the width of form elements created using ModelForm in Django

How to change the width of a textarea form element if I used ModelForm to create it?

Here is my product class:

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

And the template code ...

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

f is the actual form element ...

+47
python html django django-forms django-templates
Sep 21 '08 at 6:15
source share
3 answers

The easiest way to use is to use CSS . This is a language for defining a presentation. Look at the code generated by the form, pay attention to the identifiers for the fields you are interested in and change the appearance of these fields using CSS.

Example for the long_desc field in your ProductForm (when your form does not have a user prefix):

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

The second approach is to pass the attrs keyword to your widget constructor.

 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 

It is described in the Django documentation .

The third approach is to leave the nice declarative interface of newforms for a while and set the widget attributes to the user constructor.

 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 

This approach has the following advantages:

  • You can define widget attributes for fields that are automatically generated from your model without overriding whole fields.
  • It does not depend on the prefix of your form.
+99
Sep 21 '08 at 6:44
source share

Zuber's excellent answer, but I believe that there is an error in the code sample for the third approach. The constructor should be:

 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 

Field objects do not have attrs attributes, but their widgets.

+15
Mar 12 '09 at 22:02
source share

If you use an add-on such as Grappelli that makes heavy use of styles, you may find that any overridden row and col attributes are ignored due to CSS selectors acting on your widget. This can happen when using the excellent second or third zuber approach.

In this case, simply use the first approach mixed with either the second or third approach, setting the "style" attribute instead of the "rows" and "cols" attributes.

Here is an example where init was modified in the third approach above:

 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;' 
+4
Aug 07 '14 at 21:08
source share



All Articles