在绑定的Django管理表单中分配初始字段值

时间:2011-12-12 15:53:46

标签: django django-admin

我有一个相当简单的Django应用程序(Red Hat上的v1.3),我正在使用admin应用程序来创建和修改数据库记录。我的基础模型中的一个字段是日期字段。每次在管理员的新建或编辑表单中显示相应的字段时,我希望此字段的初始值为今天的日期(和时间)。如果愿意,用户可以选择在此后修改它。

我知道我可以在模型定义中设置默认字段值(即在models.py中)。在首次创建数据库记录时,该工作正常。但是对于随后的更改调用形式,我已经分配给默认参数(datetime.datetime.now)的可调用内容显然不会被调用。

我已经看过 - 并尝试过 - 很好地提供了stackoverflow中其他地方描述的所有提议解决方案,但没有成功。其中大多数似乎都围绕着将初始化代码插入到ModelForm子类中,例如这样的事情......

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

或类似的东西......

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

但这些方法都不奏效。初始字段值始终设置为存储在数据库中的值。我对Django文档的阅读是,在表单中强加初始字段值的各种方法仅适用于未绑定表单,而不适用于绑定表单。正确?

但是这种能力(有选择地覆盖当前存储的值)似乎是一种流行的要求,我确信必须有办法实现它。

有没有人成功地做到了这一点?

提前致谢,

菲尔

5 个答案:

答案 0 :(得分:4)

这是一种可行的方法。在模型管理类中,在绑定表单之前更改obj.a_date_field的值。日期字段的“默认”值应为新值。

class MyModelAdmin(ModelAdmin):
    ...
    def get_object(self, request, object_id):
        obj = super(MyModelAdmin, self).get_object(request, object_id)
        if obj is not None:
            obj.a_date_field = datetime.now()
        return obj

请注意,get_object没有记录,所以这有点笨拙。

答案 1 :(得分:4)

在Django 1.4中,模型声明中的default=<callable>效果很好:

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

每次添加记录时,都会更新字段的默认值。

但是使用字段的default参数会导致DateField对象的管理日志历史记录出现问题,即每次记录为未更改时也会更改。所以我采用了基于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',)

答案 2 :(得分:1)

我遇到了类似的问题,我从here

找到了解决方案

我认为你想要做的是:

class yourAdminModel(admin.ModelAdmin):

    fields = ['your_date_field']

    def add_view(self, request, form_url="", extra_context=None):
        data = request.GET.copy()
        data['your_date_field'] = datetime.date.today() # or whatever u need
        request.GET = data
        return super(yourAdminModel, self).add_view(request, form_url="", extra_context=extra_context)

答案 3 :(得分:0)

应该能够将auto_now与你的DateTime字段一起使用,according to the docs每次保存表单时都会自动将值设置为now()

答案 4 :(得分:0)

从Django 1.7开始,ModelAdmin中有一个函数get_changeform_initial_data来设置初始表单值:

def get_changeform_initial_data(self, request):
    return {'dt': datetime.now()}