Django Admin: Using a custom widget for only one model field Django Admin: Using a custom widget for only one model field django django

Django Admin: Using a custom widget for only one model field


Create a custom ModelForm for your ModelAdmin and add 'widgets' to its Meta class, like so:

class StopAdminForm(forms.ModelForm):  class Meta:    model = Stop    widgets = {      'approve_ts': ApproveStopWidget(),    }    fields = '__all__'class StopAdmin(admin.ModelAdmin):  form = StopAdminForm

Done!

Documentation for this is sort of non-intuitively placed in the ModelForm docs, without any mention to it given in the admin docs. See: Creating forms from models


After digging into the admin, model field and form field code, I believe the only way to carry out what I want is by creating a custom model field:

models.py

from django.db import modelsfrom widgets import ApproveStopWidgetclass ApproveStopModelField(models.DateTimeField):    passclass Stop(models.model):    # Other fields    approve_ts = ApproveStopModelField('Approve place', null=True, blank=True)

admin.py

from widgets import ApproveStopWidgetfrom models import ApproveStopModelFieldclass StopAdmin(admin.ModelAdmin):    formfield_overrides = {        ApproveStopModelField: {'widget': ApproveStopWidget }    }

It gets the job done.

For the time being, I'll leave the question unanswered because I have the habit of missing the obvious. Perhaps some Django smartypants has a better solution.


Override formfield_for_dbfield like thus:

class VehicleAdmin(admin.ModelAdmin):    search_fields = ["name", "colour"]    def formfield_for_dbfield(self, db_field, **kwargs):        if db_field.name == 'colour':            kwargs['widget'] = ColourChooserWidget        return super(VehicleAdmin, self).formfield_for_dbfield(db_field,**kwargs)

(credit to http://www.kryogenix.org/days/2008/03/28/overriding-a-single-field-in-the-django-admin-using-newforms-admin/ )