When I add a new model to the Django app at work, I try to make sure the results in the Django admin have good usability, too. Just because it’ll be mainly developers (and a few project managers) seeing it doesn’t mean I can neglect usability. Consequently, I spend some time on hacking the Django admin. My manager says I’ve been making it do things he didn’t even realize were possible.
The most recent thing I did was add a color field to a model. I considered Django Colorfield, but there’s an open issue about it using GPLv3-licensed code while being MIT-licensed. 😬 So, I dug around a bit.
First, I set up the model to have a
primary_color that’s a
CharField of length 7, to accommodate a standard
"#FF00FF" RGB HEX code.
class MyModel(models.Model): primary_color = models.CharField(max_length=7, default="#FFFFFF")
Then, I found a StackOverflow answer that pointed out that the Django docs include how to override the widget used for a form element, so you can change which HTML5 rendering is used for
<input> fields. Cool! So I just needed to add a
forms.py like this:
and update the
admin.py to use it:
from myapp.forms import MyModelForm @admin.register(MyModel) class MyModel(admin.ModelAdmin): form = MyModelForm
and I’d be all set, right? Indeed, it did now show me a filled-in color block in the admin!
But I still wasn’t happy. I wanted a way to see the HEX code for the color just by looking at it in the admin. With the HTML5 element’s behavior, you have to click on the color block to get a pop-up color picker and go from there to find the HEX. In Chrome on my Mac, I had to click two more times to get it to HEX mode. Ugh.
So, I dug around some more. I wasn’t able to find a way to display the HEX alongside the color block, so I decided to try for putting it in a tooltip. I needed a way to get the instance of the form field, so I could read its value. With further searching, I stumbled upon a mostly-unrelated StackOverflow answer that mentioned
self.instance. Great, now I just had to figure out where
self was accessible from in
ModelForm. Almost there! After consulting the Django docs to see which methods have access to
self, I landed on this solution. In that same
MyModelForm class in
forms.py, I added:
This grabs the value of the color field and sets it as the title attribute on the element. Title attributes display as tooltips in the browser.