如何在Django中将表单输入关联到模型?

2 投票
4 回答
1643 浏览
提问于 2025-04-15 13:21

在Django中,我怎么把一个表单和一个模型关联起来,这样在表单中输入的数据就能插入到和模型相关的数据库表里呢?我该怎么把用户输入的数据保存到那个数据库表中呢?

举个例子:

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看起来确实是一个更干净的解决方案。

4 个回答

1

我觉得ModelForm.save的说明应该讲得更清楚一些。使用它的基础类(Form)时,你需要手动用Form.cleaned_data()来获取字段的值,然后把这些值一个个设置到对应的模型字段里。而ModelForm会为你自动完成这些工作。

2

我不太确定你指的是哪个类。我知道之前有一个助手,类似于 form_for_model(具体名字我记不太清了;那是在1.0版本发布之前的事)。现在我这样做:

import myproject.myapp.models as models

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

要了解背后的元类魔法,你得看看代码,因为有很多东西需要解释 :]. 表单的构造函数可以接受一个 instance 参数。传入这个参数后,表单就会对一个已有的记录进行操作,而不是创建一个新的记录。更多信息可以在 这里找到。

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>

这只是我从这里提取的一个例子。

撰写回答