Take the 2-minute tour ×

I have

class Cab(models.Model):
    name  = models.CharField( max_length=20 )
    descr = models.CharField( max_length=2000 )

class Cab_Admin(admin.ModelAdmin):
    ordering     = ('name',)
    list_display = ('name','descr', )
    # what to write here to make descr using TextArea?

admin.site.register( Cab, Cab_Admin )

how to assign TextArea widget to 'descr' field in admin interface?

In Admin interface only!

Good idea to use ModelForm.

share|improve this question
add comment

6 Answers

up vote 45 down vote accepted

You will have to create a forms.ModelForm that will describe how you want the descr field to be displayed, and then tell admin.ModelAdmin to use that form. For example:

from django import forms
class CabModelForm( forms.ModelForm ):
    descr = forms.CharField( widget=forms.Textarea )
    class Meta:
        model = Cab

class Cab_Admin( admin.ModelAdmin ):
    form = CabModelForm

The form attribute of admin.ModelAdmin is documented in the official Django documentation. Here is one place to look at.

share|improve this answer
For simply replacing a form widget, you don't have to create your own entire form. You can just override formfield_for_dbfield on your ModelAdmin, see my answer below. –  Carl Meyer Dec 2 '13 at 20:25
add comment

For this case, the best option is probably just to use a TextField instead of CharField in your model. You can also override the formfield_for_dbfield method of your ModelAdmin class:

class CabAdmin(admin.ModelAdmin):
    def formfield_for_dbfield(self, db_field, **kwargs):
        formfield = super(CabAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == 'descr':
            formfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
        return formfield
share|improve this answer
is there any downside in this compared to the selected answer? this looks cleaner to implement as we don't need to create a new ModelForm... –  Filipe Pina Feb 23 '12 at 10:30
replaced formfield.widget = forms.Textarea() with formfield.widget = forms.Textarea(attrs=formfield.widget.attrs) to keep all attributes automatically generated for the TextField, Thanks! –  Filipe Pina Feb 23 '12 at 10:53
I don't know why the other answer is accepted over this one; I think if all you're doing is replacing a widget this is simpler. But either will work fine. –  Carl Meyer Feb 23 '12 at 15:20
add comment

Ayaz has pretty much spot on, except for a slight change(?!):

class MessageAdminForm(forms.ModelForm):
    class Meta:
        model = Message
        widgets = {
            'text': forms.Textarea(attrs={'cols': 80, 'rows': 20}),

class MessageAdmin(admin.ModelAdmin):
    form = MessageAdminForm
admin.site.register(Message, MessageAdmin)

So, you don't need to redefine a field in the ModelForm to change it's widget, just set the widgets dict in Meta.

share|improve this answer
This does retain more "automatic" properties than Ayaz's answer, but any tip on how to keep the field length validation as well? –  Filipe Pina Feb 23 '12 at 10:44
add comment

You can subclass your own field with needed formfield method:

class CharFieldWithTextarea(models.CharField):
    def formfield(self, **kwargs):
            "widget": forms.Textarea
         return super(CharFieldWithTextarea, self).formfield(**kwargs)

This will take affect on all generated forms.

share|improve this answer
add comment

Instead of a models.CharField, use a models.TextField for descr.

share|improve this answer
Unfortunately, max_length= is totally ignored by Django on a TextField, so when you need field length validation (such as letting secretaries enter event summaries) the only way to get it is to use a CharField. But a CharField is way to short to type 300 chars into. Hence the ayaz solution. –  shacker Apr 21 '09 at 23:45
Absolutely! Thanks. –  Dan Jan 26 '12 at 0:58
This isn't a good answer because it changes the database. The point of changing the widget is to change how the field is displayed, not to change the database schema –  omouse Feb 14 '13 at 21:11
add comment

If you are trying to change the Textarea on admin.py, this is the solution that worked for me:

from django import forms
from django.contrib import admin
from django.db import models
from django.forms import TextInput, Textarea

from books.models import Book

class BookForm(forms.ModelForm):
    class Meta:
        model = Book

class BookAdmin(admin.ModelAdmin):
    form = BookForm

admin.site.register(Book, BookAdmin)

If you are using a MySQL DB, your column length will usually be autoset to 250 characters, so you will want to run an ALTER TABLE to change the length in you MySQL DB, so that you can take advantage of the new larger Textarea that you have in you Admin Django site.

share|improve this answer
add comment

Your Answer


