【问题标题】:How do I associate input to a Form with a Model in Django?如何在 Django 中将表单的输入与模型相关联?
【发布时间】:2009-08-03 18:06:07
【问题描述】:

在 Django 中,如何将 Form 与 Model 关联起来,以便将输入到表单中的数据插入到与 Model 关联的数据库表中?如何将该用户输入保存到该数据库表中?

例如:

class PhoneNumber(models.Model):
    FirstName = models.CharField(max_length=30)
    LastName = models.CharField(max_length=30)
    PhoneNumber = models.CharField(max_length=20)

class PhoneNumber(forms.Form):
    FirstName = forms.CharField(max_length=30)
    LastName = forms.CharField(max_length=30)
    PhoneNumber = forms.CharField(max_length=20)

我知道有一个从模型创建表单的类,但即使在那里我也不清楚数据是如何实际进入数据库的。在我开始节省时间之前,我想了解内部工作原理。如果在文档中有一个简单的例子说明这是如何工作的,我已经错过了。

谢谢。

更新: 需要明确的是——我确实知道 ModelForm 工具,我正试图弄清楚如何在没有它的情况下做到这一点——部分原因是我可以更好地理解它首先在做什么。

回答:

在答案的帮助下,我得出了这个解决方案:

表格定义:

class ThisForm(forms.Form)
    [various Field assignments]

    model = ThisModel()

视图中的代码将输入的数据保存到数据库:

if request_method == 'POST':
    form = ThisForm(request.POST)
    if form.is_valid():
        for key, value in form.cleaned_data.items():
            setattr(form.model, key, value)
        form.model.save(form.model)

在此之后,在浏览器表单中输入的数据在数据库表中。

请注意,调用模型的 save() 方法需要传递模型本身作为参数。我不知道为什么。

警告:我是新手。这成功地将数据从浏览器获取到数据库表,但上帝只知道我在此过程中忽略、错过或彻底破坏了什么。 ModelForm 看起来绝对是一个更清洁的解决方案。

【问题讨论】:

  • 实际上,我确信 Guido 知道。可能还有其他一些。

标签: python django


【解决方案1】:

当我第一次使用表单和模型(不使用 ModelForm)时,我记得做的是检查表单是否有效,这将设置您清理的数据,手动将数据从表单移动到模型(或任何其他处理你想要做的),然后保存模型。如您所知,当您的表单完全(甚至非常接近)匹配您的模型时,这是非常乏味的。通过使用 ModelForm(因为您说您不太确定它是如何工作的),当您保存 ModelForm 时,它会根据模型规范使用表单数据实例化一个对象,然后为您保存该模型。总而言之,数据流从 HTML 表单,到 Django 表单,到 Django 模型,再到数据库。

您的问题的一些实际代码:

将浏览器表单数据获取到表单对象中:

if request.method == 'POST':
    form = SomeForm(request.POST)
    if form.is_valid():
        model.attr = form.cleaned_data['attr']
        model.attr2 = form.cleaned_data['attr2']
        model.save()
else:
    form = SomeForm()
return render_to_response('page.html', {'form': form, })

在模板页面中,您可以使用表单执行以下操作:

<form method="POST">
{{ form.as_p }}
<input type="submit"/>
</form>

这只是我从here 中提取的一个示例。

【讨论】:

  • 因此,您可以将模型分配给表单的属性,可能是通过 Meta,正如 gavoja 建议的那样,并使用该模型的 save() 方法。我想数据移动可以通过循环clean_data.keys()并使用setattr(model,key,cleaned_data [key])来自动化。我认为这会满足我的需要——我会尝试的。
【解决方案2】:

我不确定你指的是哪个班级。我知道有一个助手,例如form_for_model(不记得确切的名称;那是在 1.0 版本发布之前)。现在我是这样的:

import myproject.myapp.models as models

class PhoneNumberForm(forms.ModelForm):
    class Meta:
        model = models.PhoneNumber

要了解背后的元类魔法,您必须查看代码,因为要解释的内容很多:]。表单的构造函数可以采用instance 参数。传递它将使表单对现有记录进行操作,而不是创建新记录。更多信息here

【讨论】:

  • 我可以将表单显示到浏览器屏幕上,以便用户输入数据。如何将该数据获取到正确的数据库表中?
  • 谢谢,这帮助我意识到我应该明确地分配给模型属性。
【解决方案3】:

我认为ModelForm.save 文档应该解释它。使用它的基类 (Form),您需要使用 Form.cleaned_data() 来获取字段值并将它们“手动”设置为适当的模型字段。 ModelForm 为您完成所有这些工作。

【讨论】:

    【解决方案4】:

    Django 文档在这个主题上非常清楚。不过,这里有一个粗略的入门指南:您可以覆盖表单的保存方法或在视图中实现该功能。

    if form.is_valid() # validation - first the fields, then the form itself is validated
        form.save()
    

    表格内:

    def save(self, *args, **kwargs):
        foo = Foo()
        foo.somefield = self.cleaned_data['somefield']
        foo.otherfield = self.cleaned_data['otherfield']
        ...
        return foo.save()
    

    【讨论】:

    • 朋友,如果文档清楚,我已经错过了。我已经阅读过该文档一两次了。
    猜你喜欢
    • 2013-12-10
    • 1970-01-01
    • 2013-09-13
    • 2012-12-24
    • 2014-12-14
    • 1970-01-01
    • 2019-08-01
    • 2018-12-23
    • 2014-09-17
    相关资源
    最近更新 更多