Microseconds in TimeField overridden to zero in Django Admin

When using a TimeField in a Django model, the microseconds part of the time value is always set to 0 after click save. Although the database stores the microseconds correctly (e.g., 15:42:21.222000), the admin panel rounds or truncates them, often displaying 15:42:21 instead. This can cause confusion for users who rely on precise time values. As updating any other field in the instance from the admin form, it overrides the microseconds part of the time to be .00000.

I Found this part in the Django docs in the part related to the Widgets:

By default, the microseconds part of the time value is always set to 0 . If microseconds are required, use a subclass with the supports_microseconds attribute set to True .

SO I have created a custom widget:

from django.forms.widgets import TimeInput
from django.contrib import admin

class MicrosecondTimeInput(TimeInput):
    input_type = "text"

    def __init__(self, attrs=None, format=None):
        # Set supports_microseconds to True
        self.supports_microseconds = True
        super().__init__(attrs, format)

class MyModelAdmin(admin.ModelAdmin):

    formfield_overrides = {
            TimeField: {"widget": MicrosecondTimeInput(format="%H:%M:%S.%f")},
        }

And After Doing that the admin forms shows the microseconds part correctly, but the field type converted to a string not time, So it became a little confusing.

You could convert the string format like that:

from django import forms
from django.forms.widgets import TimeInput
from django.contrib import admin
from django.db.models import TimeField
from datetime import datetime

class MicrosecondTimeInput(TimeInput):
    input_type = "time"
    format = "%H:%M:%S.%f"

    def __init__(self, attrs=None, format=None):
        self.supports_microseconds = True
        super().__init__(attrs, format)

class MicrosecondTimeField(forms.TimeField):
    widget = MicrosecondTimeInput

    def to_python(self, value):
        if isinstance(value, str):
            return datetime.strptime(value, self.widget.format).time()
        return value

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        TimeField: {'form_class': MicrosecondTimeField},
    }

The to_python method returns the value as a time object, even if it’s initially a string.

If you use a time input, by default it only shows hours and minutes, as you’ve found.

But if you specify the step attribute like this, it displays microseconds:

<input name="start" type="time" step="0.001">

Here’s a field with no step attribute, and one with the above value:

I don’t know how supported this is, but it seems to work in macOS Safari, Chrome and Firefox that I have to hand.

But I don’t know if Django would still remove the microseconds? Anyway, with @anefta’s suggestions, this might provide a nicer front-end experience.