50

Disclaimer: I am a beginner with python and Django but have Drupal programming experience.

How can I override the default widget of this:

#models.py
class Project(models.Model):
color_mode = models.CharField(max_length=50, null=True, blank=True, help_text='colors - e.g black and white, grayscale')

in my form with a select box? Is the following OK or am I missing something?

#forms.py
from django.forms import ModelForm, Select
class ProjectForm(ModelForm):
    class Meta:
        model = Project
        fields = ('title', 'date_created', 'path', 'color_mode')
        colors = (
                   ('mixed', 'Mixed (i.e. some color or grayscale, some black and white)'),
                   ('color_grayscale', 'Color / Grayscale'),
                   ('black_and_white', 'Black and White only'),
                   )
        widgets = {'color_mode': Select(choices=colors)}

After reading https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-default-field-types-or-widgets, I am lost since the example only discusses TextArea and the widgets discussion seems to exclude ModelForm.

Thanks!

vishes_shell
  • 22,409
  • 6
  • 71
  • 81
mellow-yellow
  • 1,670
  • 1
  • 18
  • 38

1 Answers1

130

If you want to override the widget for a formfield in general, the best way is to set the widgets attribute of the ModelForm Meta class:

To specify a custom widget for a field, use the widgets attribute of the inner Meta class. This should be a dictionary mapping field names to widget classes or instances.

For example, if you want the a CharField for the name attribute of Author to be represented by a <textarea> instead of its default <input type="text">, you can override the field’s widget:

from django.forms import ModelForm, Textarea
from myapp.models import Author

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ('name', 'title', 'birth_date')
        widgets = {
            'name': Textarea(attrs={'cols': 80, 'rows': 20}),
        }

The widgets dictionary accepts either widget instances (e.g., Textarea(...)) or classes (e.g., Textarea).

https://docs.djangoproject.com/en/3.2/topics/forms/modelforms/#overriding-the-default-fields

Alex
  • 9
  • 3
qris
  • 7,900
  • 3
  • 44
  • 47
  • This really deserves an upvote. But sadly, the django documents didn't mention how to add widgets to a model.form class. So stupid and disappointing. The django docs are tedious and long but didn't contain what are really important to developers. – Alston Oct 16 '22 at 10:19