【发布时间】:2015-04-24 01:46:51
【问题描述】:
所以我正在使用 Django 1.8 Alpha 代码库,并想看看其他人是否遇到了这个有趣的问题。我有一个 ModelForm:
class ChildForm(forms.ModelForm):
class Meta:
model = Child
fields = ('first_name', 'last_name', 'gender', 'birthday', 'avatar')
我也有我的看法:
@login_required
def edit_child(request, id):
"""Edit a child"""
child = get_object_or_404(Child, pk=id)
if not child.parent == request.user:
raise Http404()
form = ChildForm(request.POST, request.FILES, instance=child)
if request.method == 'POST' and form.is_valid():
form.save()
return redirect('dashboard')
context = {
'child': child,
'form': form
}
return render(request, 'edit_child.html', context)
当我在模板中呈现表单时,一切正常,减去一件事。初始值为空。在过去的 Django 版本中,同时使用 request.POST 和 instance=child 允许实例通过并填写表单。但出于某种奇怪的原因,它似乎接受 request.POST 作为初始状态而不是实例。调试中:
- 表单已绑定
- 表单中的初始数据设置正确
- 实例设置正确
唯一的问题是渲染。为了展示,这里是我的模板,使用crispy_forms 进行表单渲染:
<form role="form" method="post" action="{{ child.get_edit_url }}" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-default">Save</button>
</form>
任何人以前见过这个或看到我明显做错了什么?
【问题讨论】:
-
通常你不会将 request.POST 传递给表单,除非它实际上是一个帖子。
-
@DanielRoseman 在某些情况下,是的,您可以在检查 POST 后定义表单,但 Django 允许您将其作为更快更干净的解决方案来执行,如您在此处看到的:docs.djangoproject.com/en/1.8/topics/forms/modelforms/…
-
我不确定该链接应该向我展示什么。他们在那里使用 POST 数据在保存表单之前对其进行实例化。您不应将数据传递给初始显示;除了绑定它并触发验证之外的任何其他内容,因此您会在第一次显示时遇到任何错误,这很少是您想要的。
-
@DanielRoseman 这不是它的工作原理。本质上,它是一个字典合并,其中 request.POST = {} 在 GET 请求上,并且实例本身具有所有已定义的键和值。因此,在 GET 请求中,没有任何内容被覆盖,但是当 POST 请求通过时,相关的密钥会被更新。这个想法是,如果有错误,您希望为用户组合实例和更新的帖子数据。或者我相信。该链接或多或少是一种表明以这种方式初始化表单是 Django “事物”的一种方式。
-
合并发生在
initialdict,而不是data或files。如果data和filesis not None之一,则认为您的表单已绑定。如果绑定表单时data中缺少某个键,则认为该键已被用户显式删除,因此将为空。
标签: python django django-forms