Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to I change the rendering of a specific field type in Django admin?

For example I have an IntegerField and I want to change how it is displayed all across Django admin.

I considered subclassing it and overriding __str__ and __unicode__ methods but it doesn't seam to work.

class Duration(models.IntegerField):
    def __unicode__(self):
        return "x" + str(datetime.timedelta(0, self))
    def __str__(self):
        return "y" + str(datetime.timedelta(0, self))

Update: I just want to chage the way the field is displayed, not the edit control (widget).

like image 754
sorin Avatar asked Dec 31 '25 12:12

sorin


2 Answers

I'm not sure what you want to do with the field, but if you want to change the HTML that is displayed, you need to either change the widget that the form field is using, or create your own custom widget:

https://docs.djangoproject.com/en/dev/ref/forms/widgets/

models.py

class LovelyModel(models.Model):
    my_int = models.IntegerField()

forms.py

from widgets import WhateverWidgetIWant

class LovelyModelForm(forms.ModelForm):
    my_int = models.IntegerField(widget=WhateverWidgetIWant())

    class Meta:
        model = LovelyModel

admin.py

from forms import LovelyModelForm

class LovelyModelAdmin(admin.ModelAdmin):
    form = LovelyModelForm

What is it you are trying to do?

like image 135
Timmy O'Mahony Avatar answered Jan 04 '26 00:01

Timmy O'Mahony


I think you need something like this (untested code)::

import datetime
from django.db import models


class Duration(models.IntegerField):
    description = "Stores the number of seconds as integer, displays as time"
    def to_python(self, value):
        # this method can receive the value right out of the db, or an instance
        if isinstance(value, models.IntegerField):
            # if an instance, return the instance
            return value
        else:
            # otherwise, return our fancy time representation
            # assuming we have a number of seconds in the db
            return "x" + str(datetime.timedelta(0, value))
    def get_db_prep_value(self, value):
        # this method catches value right before sending to db
        # split the string, skipping first character
        hours, minutes, seconds = map(int, value[1:].split(':'))
        delta = datetime.timedelta(hours=hours, minutes=minutes, seconds=seconds)
        return delta.seconds

This, however, changes how the field's value represented in Python at all, not only in admin, which may not be a desired behaviour. I.e., you have object.duration == 'x00:1:12', which would be saved to the database as 72.

See also documentation on custom fields.

like image 30
Anton Strogonoff Avatar answered Jan 04 '26 00:01

Anton Strogonoff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!