如何将表单中的输入与Django中的模型相关联?

时间:2009-08-03 18:06:07

标签: python django

在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工具,我试图弄清楚如何在没有它的情况下做到这一点 - 部分原因是我可以更好地理解它在做什么。

ANSWERED:

在anwers的帮助下,我找到了这个解决方案:

表单定义:

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()方法需要将模型本身作为参数传递。我不明白为什么。

CAVEAT:我是新手。这成功地将数据从浏览器传输到数据库表,但上帝只知道我忽略或错过了什么,或者直接打破了。 ModelForm绝对是一个更清洁的解决方案。

4 个答案:

答案 0 :(得分:3)

当我第一次使用表单和模型(不使用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提取的一个例子。

答案 1 :(得分:2)

我不确定你的意思是哪一堂课。我知道有一个帮助器,比如form_for_model(不记得确切的名字;这是1.0版本发布之前的方式)。现在我就这样:

import myproject.myapp.models as models

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

要看到背后的元类魔法,你必须查看代码,因为有很多东西要解释:]。表单的构造函数可以使用instance参数。传递它将使表单在现有记录上运行而不是创建新记录。更多信息here

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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()