Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning initial field values in bound Django admin forms

I have a fairly simple Django application (v1.3 on Red Hat) for which I'm using the admin application to create and modify database records. One of the fields in my underlying model is a date field. Each time the corresponding field is displayed in the admin's new or edit form I'd like the initial value of this field to be today's date (and time). The user may choose to modify it thereafter, if she desires.

I know that I can set the default field value within my model definition (i.e. in models.py). Which works fine when a database record is first created. But for subsequent invocations of the change form the callable that I've assigned to the default parameter (datetime.datetime.now) obviously doesn't get invoked.

I've looked at - and tried - pretty well all of the many proposed solutions described elsewhere in stackoverflow, without success. Most of these appear to revolve around inserting initialisation code into the ModelForm subclass, e.g. either something like this...

class ConstantDefAdminForm(ModelForm) :
    a_date_field = DateField(initial="datetime.datetime.now")  # or now()
    class Meta :
        model = ConstantDef
        widgets = {
            ...
        }

or something like this...

class ConstantDefAdminForm(ModelForm) :
    class Meta :
        model = ConstantDef
        widgets = {
            ...
    }
    def __init__(self, ...) :
        # some initialisation of a_date_field
        super(ConstantDefAdminForm, self).__init__(...)

But neither of these approaches work. The initial field value is always set to the value that is stored in the database. My reading of the Django documentation is that the various ways of imposing initial field values in forms only work for unbound forms, not bound forms. Right?

But this capability (to selectively override currently stored values) would seem to be such a popular requirement that I'm convinced that there must be a way to do it.

Has anyone out there succeeded in doing this?

Thanks in advance,

Phil

like image 982
Phil Avatar asked Jan 18 '23 02:01

Phil


1 Answers

In Django 1.4 the default=<callable> in model's declaration works well:

class MyModel(models.Model):
    dt = models.TimeField(null=True, blank=True, default=datetime.datetime.now)

every time you add a record the default value of the field is updated.

But the use the field's default parameter cause me some problem with the Admin log history of DateField objects, that are every time recorded as changed also when they are not modified. So I've adopted a solution based on https://stackoverflow.com/a/11145346/1838607:

import datetime

class MyModelAdminForm(forms.ModelForm):
    class Meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        super(MyModelAdminForm, self).__init__(*args, **kwargs)

        self.fields['dt'].initial = datetime.datetime.now

class MyModelAdmin(admin.ModelAdmin):
    form = MyModelAdminForm
    fields = ('dt',)
like image 97
Davide Brunato Avatar answered Jan 30 '23 20:01

Davide Brunato