预填充 Django(非模型)表单

Posted

技术标签:

【中文标题】预填充 Django(非模型)表单【英文标题】:Prepopulate Django (non-Model) Form 【发布时间】:2010-10-30 11:58:45 【问题描述】:

我正在尝试根据一些信息在我的 django 表单中预填充数据,但不使用 ModelForm,所以我不能只设置实例。

这看起来应该很容易,但由于某种原因,我找不到任何文档告诉我如何做到这一点。这是我的表格:

class MyForm(forms.Form):
  charfield1 = forms.CharField(max_length=3)
  charfield2 = forms.CharField(max_length=3)
  choicefield = forms.ModelChoiceField(MyModel.objects.all())

我试着做:

form = MyForm()
form.charfield1 = "foo"
form.charfield2 = "bar"
# a model choice field
form.choicefield = MyModel.objects.get(id=3)

这不起作用。

【问题讨论】:

【参考方案1】:

试试:

form = MyForm('charfield1': 'foo', 'charfield2': 'bar')

Form 对象的构造函数可以采用字段值字典。这将创建一个绑定表单,可用于验证数据并将表单呈现为 html 并显示数据。有关详细信息,请参阅the forms API 文档。

编辑:

为了完整起见,如果您不想绑定表单,而只想为某些字段声明初始值,则可以改用以下内容:

form = MyForm(initial='charfield1': 'foo', 'charfield2': 'bar')

详见initial values的文档。

【讨论】:

谢谢 - 这行得通。但是,它不适用于模型的外键。我尝试在字典中传入模型实例本身,这会引​​发异常,我尝试传入 pk/id,这不会失败,但没有在我的表单 UI 中正确预加载它。 使用对象 id 应该可以。我刚刚使用 ModelChoiceField 对其进行了测试。您能告诉我们您的表单定义吗? 我又测试了一遍。以下作品(2 是模型中对象的 id): MyForm('charfield1': 'foo', 'charfield2': 'bar', 'choicefield': '2')。您确定您使用的是数据库中存在的 id 吗?目前我想不出任何其他可能导致这种情况的原因。 正是我正在寻找的答案。谢谢【参考方案2】:

不管怎样,FormView 基于类的视图方法是覆盖FormViewget_initial 函数。 get_initial 返回 get_form_kwargs 用于实例化表单的初始关键字参数。

文档:

对于get_initial,here, 为get_form_kwargs、here。

示例代码:

from django.views.generic.edit import FormView

class MyFormView(FormView):

    def get_initial(self):
        initial = super(MyFormView, self).get_initial()
        # update initial field defaults with custom set default values:
        initial.update('charfield1': 'foo', 'charfield2': 'bar')
        return initial

【讨论】:

【参考方案3】:

您可以使用 model_to_dict() 将实例转换为字典,然后用它填充表单。像这样的东西应该可以工作:

from django.forms.models import model_to_dict
...
my_obj = MyModel.objects.get(abc=123)
form = MyForm(initial=model_to_dict(my_obj))

注意:我使用的是 django 1.3 版

【讨论】:

【参考方案4】:

有两种填充 Django 表单的方法。

第一种是在实例化时将字典作为第一个参数传递(或将其作为data kwarg 传递,这也是一样的)。当您想使用 POST 数据来填充和验证表单时,这就是您所做的。

data_dict = 'charfield1': 'data1', 'charfield2': 'data2', 'choicefield': 3
form = MyForm(data_dict)

但是,这将触发表单上的验证,因此只有在您实际传递有效且完整的数据开始时才有效 - 否则您将开始出现错误。

填充表单的另一种方法是使用initial 参数(记录在here)。这为表单字段提供了初始值,但 not 不会触发验证。因此,例如,如果您不填写所有值,则它是合适的。

form = MyForm(initial=data_dict)

要通过initial 填充选择字段,请使用 pk 值。

【讨论】:

基于以上,您如何向客户表单字段提供数据? @Chris,如果您有任何问题并且上面没有涵盖,请打开一个新问题并在那里提出,并提供完整的详细信息。 这是一个与此答案相关的附带问题。 焦点移到字段时初始值是否消失?我问是因为如果您想用数据预填充或初始化该字段但允许用户在输入数据时附加到该字段怎么办?或者,更好的是,在某些情况下,强制用户追加(因为无论如何验证都需要初始值)?

以上是关于预填充 Django(非模型)表单的主要内容,如果未能解决你的问题,请参考以下文章

Django:ModelForm 使用自定义查询预填充复选框

基于 Web 请求预填充 Django 表单

使用 Django 从数据库预填充 HTML 表单表

需要澄清使用 Django 1.4 表单向导,特别是预填充和保存

模型形式中的 django auto slug,例如 django admin 中的预填充字段

ASP.NET / 模型 - 防止模型预填充表单输入字段