覆盖ModelForm中的初始值

时间:2010-06-07 10:04:35

标签: python django django-forms

在我的Django(1.2)项目中,我想在模型中预填充一个字段,但我的新值被忽略了。 这是片段:

class ArtefactForm(ModelForm):
    material = CharField(widget=AutoCompleteWidget('material', force_selection=False))

    def __init__(self, *args, **kwargs):
        super(ArtefactForm, self).__init__(*args, **kwargs)
        self.fields['material'].initial = 'Test'

我也尝试了self.base_fields,但没有效果:表单中始终显示数据库值。有什么想法吗?

2 个答案:

答案 0 :(得分:40)

试试这个:

def __init__(self, *args, **kwargs):
    initial = kwargs.get('initial', {})
    initial['material'] = 'Test'
    kwargs['initial'] = initial
    super(ArtefactForm, self).__init__(*args, **kwargs)

答案 1 :(得分:12)

老问题,但添加一个描述性答案,因为我认为这对一些新的开发人员会有所帮助。

  

我也尝试使用selfbase_fields,但没有效果:表单中始终显示数据库值。有什么想法吗?

如果表单是"已初始化"形式,: -

  1. 使用initial参数(例如YourModelFrom(initial={'filed1': variable}) - 通常情况下,当您想要为某些字段传递动态计算的初始值时)。参考Setting Initial Values

  2. 使用instance参数(例如YourModelFrom(instance=model_object) - 通常情况下,当您想要更新现有的模型实例对象时)。参考文献阅读ModelFrom' save() method

    <子> 注:
    1 `ModelFrom`类继承`BaseModelFrom`类。 `BaseModelFrom`类继承`BaseForm`类 2当我们将模型类实例对象分配给instance参数(因此instance)然后`BaseModelFrom`构造函数调用时,参数instance is not None被添加到`BaseModelFrom`类构造函数中model_to_dict()之前更新initial参数以调用超类构造函数。检查BaseModelFrom类中的def __init__

  3. 然后明确地为字段分配初始值(如OP中所讨论的代码所示)不会产生影响,这是由BaseFrom方法写入def _clean_fields(self): for name, field in self.fields.items(): value = field.widget.value_from_datadict( self.data, self.files, self.add_prefix(name)) try: if isinstance(field, FileField): initial = self.initial.get(name, field.initial) # <- Check value = field.clean(value, initial) else: 的方式所致}类。

    Code Snip:

    initial = self.initial.get(name, field.initial)

    根据代码行initial,如果字段的初始值在field.initial dict中给出,则分配给self.initial的值使用。

    <强> [ANSWER]

    尽管@Daniel的答案是完全正确的,但是人们也可以通过另一种方式来实现同样的效果:def __init__(self, *args, **kwargs): super(ArtefactForm, self).__init__(*args, **kwargs) self.initial['material'] = 'Test'

    self.initial

    试一试!!

    BaseForm只不过是我们在论证中传递的词典。检查class BaseForm(object): def __init__(........ ........): : self.prefix = prefix self.initial = initial or {} # <-- Notice self.error_class = error_class : 中的代码_clean_fields

    Field

    注意:我没有找到任何与使用初始属性相关的文档,我只是探索了基本代码并使用了它。

    编辑:问题中报告的行为也记录在Django模型

      

    __init__

         

    Form.initial

         

    请注意,如果initial定义initial 包含initial   实例化表单,然后后者initial将具有优先权。   在此示例中,>>> from django import forms >>> class CommentForm(forms.Form): ... name = forms.CharField(initial='class') ... url = forms.URLField() ... comment = forms.CharField() >>> f = CommentForm(initial={'name': 'instance'}, auto_id=False) >>> print(f) <tr><th>Name:</th><td><input type="text" name="name" value="instance" /> <tr><th>Url:</th><td><input type="url" name="url" /></td></tr> <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr> 在字段级别和位置都提供   表单实例级别,后者优先:

    initial

    <子> PS:顺便说一下,我的答案第2点说明了instancedata参数之间的区别。它们是另一个键值参数{{1}} - 触发形式验证的值。阅读此Dynamic initial values