老问题,但添加了一个描述性的答案,因为我相信这对一些新开发人员会有所帮助。
我也试过self.base_fields,但没有效果:表格中总是显示数据库值。有什么想法吗?
如果表单是“初始化”表单,则:-
-
使用initial 参数(例如YourModelFrom(initial={'filed1': variable}) — 通常情况下,当您想为某些字段传递动态计算的初始值时)。参考Setting Initial Values
或
-
使用instance 参数(例如YourModelFrom(instance=model_object) — 通常情况下,当您想要更新现有模型实例对象时)。参考阅读 ModelFrom 的save() method
注意:
1 `ModelFrom` 类继承 `BaseModelFrom` 类。 `BaseModelFrom` 类继承 `BaseForm` 类。
2 参数instance 被添加到`BaseModelFrom` 类构造函数中,当我们将模型类实例对象分配给instance 参数(因此instance is not None)然后`BaseModelFrom` 构造函数调用model_to_dict() 并更新initial 参数之前调用超类构造函数。检查 BaseModelFrom 类中的def __init__
然后显式地为字段分配初始值(如相关的 OP 代码所示)不起作用,这是由于 _clean_fields 方法在 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:
根据代码行initial = self.initial.get(name, field.initial),如果字段的初始值在initial dict 中给出,则分配给field.initial 的值不使用。
[回答]:
虽然,@Daniel 的答案是完全正确的,但人们也可以喜欢另一种达到相同效果的方法是使用self.initial:
def __init__(self, *args, **kwargs):
super(ArtefactForm, self).__init__(*args, **kwargs)
self.initial['material'] = 'Test'
试试看!!
self.initial 只不过是我们在参数中传递的字典。 BaseForm中的校验码__init__:
class BaseForm(object):
def __init__(........
........):
:
self.prefix = prefix
self.initial = initial or {} # <-- Notice
self.error_class = error_class
:
注意:我没有找到任何与使用初始属性相关的文档,我只是探索了基础代码并使用了它。
编辑:问题中报告的行为也记录在 Django 模型中
Form.initial
请注意,如果 Field 定义了 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>
PS:顺便说一句,我的答案中的第 2 点说明了 initial 和 instance 参数之间的区别。它们是另一个键值参数data - 触发表单验证的值。阅读此Difference between Django Form 'initial' and 'bound data'?。