Changing widget for a datetime type

Hello all!

Let’s assume I have a model with a DateTime Field like so:

class A(models.Model):
    replaced_at = models.DateTimeField(null=True, blank=True)

    def save(self, *args, **kwargs):
        self.display_at = self.display_at.replace(hours=1, minute=0)

        super().save(*args, **kwargs)

As you can see I override the time part of the datetime for $reasons. But I still need that time part (aka the answer is not to switch to a models.DateField).

I wanted to hide the time part from the users because in effect they don’t control it (as it will be overriden anyway).

I tried overriding the widget like so:

class AAdminForm(forms.ModelForm):
    class Meta:
        model = A
        fields = "__all__"
        widgets = {
            "replaced_at": admin.widgets.AdminDateWidget,
        }

But doing that I end up with validation error when trying to add an instance of A through the admin:
“* Enter a list of values.”

Is there a canonical way to do this? (Basically, hide the time part of a datetime field in the admin).

Thanks.

Not that I can find.

<conjecture>
If I understand what I’m looking at, it appears that the admin uses, by default, the AdminSplitDateTime widget, where widgets = [AdminDateWidget, AdminTimeWidget].

One of the “easier” solutions I can think of would be to create a custom AdminSplitDateTime widget that uses a custom AdminTimeWidget - one that simply uses a hidden (and possibly disabled) CharField for input.

Another option would be to override the template defined in the AdminSplitDateTime to not render the time widget. (django.contrib.admin.templates.admin.widgets.split_datetime.html)
<conjecture>

Okay good ! Yeah I tried introducing the custom AdminTimeWidget but because I also use this in an Inline I ended up with more errors.

I haven’t thought of overriding the template, that might do the trick!

Thanks I’ll keep you updated on the final solution that I use.