表单只是简化和加速(开发)从请求中获取POST数据的过程的工具。手动的方式是为所有的字段做一些HTML格式的request.POST.get('somefield')
。但是Django的可以做的比这更好的...
在本质上,一个Form类包含若干领域,并执行以下任务:
- 显示HTML输入,
- 收集和验证数据时用户提交它
- 如果字段不验证,则返回值和错误消息为HTML
- 如果所有字段都是有效的,请提供
form.cleaned_data
字典作为访问这些值的便捷方式。
使用这些值,我可以手动创建一个MyModel
的新实例并保存它。当然,我必须在MyModel模型中的每个字段的表单中定义一个字段。
这意味着,基本上,我可以做这样的事情:
(原谅我没有测试此代码,所以我不能保证它的正确率100%)
models.py:
class MyModel(models.Model):
field1 = models.CharField(max_length=40, blank=False, null=False)
field2 = models.CharField(max_length=60, blank=True, null=True)
forms.py:
class FormForMyModel(forms.Form):
form_field1 = forms.CharField(max_length=40, required=True)
form_field2 = forms.CharField(max_length=60, required=False)
views.py:
def create_a_my_model(request):
if request.method == 'POST':
form = FormForMyModel(request.POST)
if form.is_valid():
my_model = MyModel()
my_model.field1 = form.cleaned_data.get('form_field1', 'default1')
my_model.field2 = form.cleaned_data.get('form_field2', 'default2')
my_model.save()
else:
form = FormForMyModel()
context_data = {'form': form}
return HttpResponse('templtate.html', context_data)
(这可以用少量代码写成,但它应该尽可能清晰)
注意模型字段和表单字段之间没有关系!创建MyModel实例时,我们必须手动分配值。
上面的例子概述了通用表格工作流程。它经常在复杂情况下需要,但不是像这个例子那样简单。
对于这个例子(和现实世界的例子很多),Django的可以做的比这更好的...
您可以注意到在上面例如两个恼人的问题:
- 我有分别在
MyModel
和FormForMyModel
的字段上定义字段。然而,这两个字段组(类型)之间有很多相似之处,所以这是一种重复的工作。当添加标签,验证程序等时,相似性会增加。
- 创建
MyModel
实例有点愚蠢,必须手动分配所有这些值。
这是一个的ModelForm用武之地。
这些行为基本上就像一个普通的形式(实际上,他们是从常规模式扩展),但他们能救我的一些工作(我刚刚概述的两个问题当然是:))。
所以回到两个问题:
而不是定义表单字段为每个模型场,我只是在该Meta
类中定义model = MyModel
。这指示表单自动从模型字段生成表单字段。
模型表格有save
方法可用。这可以用来在视图中的一行中创建模型的实例,而不是手动分配字段。
所以,让我们对上面有ModelForm
的例子:
models.py:
class MyModel(models.Model):
field1 = models.CharField(max_length=40, blank=False, null=False)
field2 = models.CharField(max_length=60, blank=True, null=True)
forms.py:
class MyModelForm(forms.ModelForm): # extending ModelForm, not Form as before
class Meta:
model = MyModel
views.py:
def create_a_my_model(request):
if request.method == 'POST':
form = MyModelForm(request.POST)
if form.is_valid():
# save the model to database, directly from the form:
my_model = form.save() # reference to my_model is often not needed at all, a simple form.save() is ok
# alternatively:
# my_model = form.save(commit=False) # create model, but don't save to database
# my.model.something = whatever # if I need to do something before saving it
# my.model.save()
else:
form = MyModelForm()
context_data = {'form': form}
return HttpResponse('templtate.html', context_data)
希望这清除了的Django的使用形成了一个位。
只需再注意一点 - 在ModelForm
上定义表单域是完全可以的。这些将不会在form.save()
中使用,但仍可以使用form.cleaned_data
,就像使用常规表单一样。
阅读教程https://docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs/和https://docs.djangoproject.com/en/dev/topics/forms/?from = olddocs。 – 2012-08-12 15:23:41
我见过这两篇文章,我会再读一遍。我希望了解表单,视图和模板之间的关系,以及如何创建一个下拉列表..我想也许它只是带我有时间消化..如果其他人可以腾出时间解释这一点,我会非常高兴! – Oli 2012-08-12 16:27:30