Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a DateTimeField field in my model. I wanted to display it as a checkbox widget in the Django admin site. To do this, I created a custom form widget. However, I do not know how to use my custom widget for only this one field.

The Django documentation explains how to use a custom widget for all fields of a certain type:

class StopAdmin(admin.ModelAdmin):     formfield_overrides = {         models.DateTimeField: {'widget': ApproveStopWidget }     } 

This is not granular enough though. I want to change it for only one field.

like image 677
Belmin Fernandez Avatar asked Nov 14 '10 07:11

Belmin Fernandez


People also ask

How do I hide fields in Django admin?

In Django 1.8 exclude = ('fieldname',) does works with admin. ModelAdmin so one does not have to inherit from InlineModelAdmin anymore. Also works in Django 1.6.

Is it possible to create a custom admin view without a model behind it?

Show activity on this post. The most straightforward answer is "no". As the Django Book says, the admin is for "Trusted users editing structured content," in this case the structured content being models arranged in hierarchies and configured through settings.py.

How do I automatically register all models in Django admin?

To automate this process, we can programmatically fetch all the models in the project and register them with the admin interface. Open admin.py file and add this code to it. This will fetch all the models in all apps and registers them with the admin interface.


2 Answers

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

like image 168
Chris Pratt Avatar answered Sep 29 '22 04:09

Chris Pratt


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 models from widgets import ApproveStopWidget  class ApproveStopModelField(models.DateTimeField):     pass  class Stop(models.model):     # Other fields     approve_ts = ApproveStopModelField('Approve place', null=True, blank=True) 

admin.py

from widgets import ApproveStopWidget from models import ApproveStopModelField  class 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.

like image 26
Belmin Fernandez Avatar answered Sep 29 '22 06:09

Belmin Fernandez