【问题标题】:Django 1.8 ModelForm request.POST supersedes instanceDjango 1.8 ModelForm request.POST 取代实例
【发布时间】: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.POSTinstance=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 “事物”的一种方式。
  • 合并发生在initial dict,而不是datafiles。如果datafiles is not None 之一,则认为您的表单已绑定。如果绑定表单时data中缺少某个键,则认为该键已被用户显式删除,因此将为空。

标签: python django django-forms


【解决方案1】:

所以事实证明,如果为 BOTH 文件和发布数据返回 dict,我需要显式设置 None

form = ChildForm(request.POST or None, request.FILES or None, instance=child)

继续。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 2012-08-31
    • 2012-03-31
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多