为什么没有办法改变绑定到Django表单的数据?

时间:2014-01-22 11:46:22

标签: django django-forms

我花了几个小时试图理解为什么我不能执行保存模型操作,只创建一个用于保存和验证的表单实例以及渲染空白表单。 (我有很多Yii背景。)

我遇到了一个问题,我根本无法将数据设置为模型(Django术语中的“bind”)。当我必须创建不同模型时,从Django文档开始的方式对我来说似乎很难看。

然后我在Django文档中找到了这个。

  

如果您有一个绑定的Form实例并想以某种方式更改数据,或者您想要将未绑定的Form实例绑定到某些数据,请创建另一个Form实例。无法更改Form实例中的数据。一旦创建了Form实例,您应该认为它的数据是不可变的,无论它是否有数据。

我理解这种限制是出于某种特殊原因。那么,这是什么原因?

UPD 查看代码示例

def register(request: HttpRequest) -> HttpResponse:
    organization = forms.Organization()
    if request.method == 'POST':
        organization.data = request.POST
        organization.full_clean()
        if organization.is_valid():
            organization.save()
            return HttpResponseRedirect(reverse('view'))
    return render(request, 'main/organizations/register.html', {
        'form': organization,
    })

使用Crispy Forms执行渲染。只需{% crispy form %}

表单是简单的模型形式。

1 个答案:

答案 0 :(得分:1)

目前还不是很清楚你要问的是什么,但这里有一个模型形式的简单示例:

from django.shortcuts import render

def myview(request):
    form = MyModelForm(data=request.POST or None)
    if form.is_valid()
        saved_obj = form.save()
        return redirect('success_url')
    return render(request, 'myform_template.html', {'form': form})

当您最初访问该视图时,您将获得一个空白表单(因为request.POST为空,因此表单数据为None,即表单不是“绑定”。

您应该在HTML中设置表单操作以发布到相同的网址,最简单的方法是空白操作:<form action="" method="post">

当您提交表单时,request.POST将包含提交的数据,因此表单将被绑定。如果表单有效,我们保存一个新的模型实例,那么重定向是一个好习惯。如果表单无效,表单将重新显示用户提交的数据以及错误消息。

如果要编辑现有模型实例,则模式如下所示:

from django.shortcuts import render, get_object_or_404

def myview(request, pk):
    existing_obj = get_object_or_404(MyModel, pk=pk)
    form = MyModelForm(data=request.POST or None, instance=existing_obj)
    if form.is_valid()
        saved_obj = form.save()
        return redirect('success_url')
    return render(request, 'myform_template.html', {'form': form})

在这种情况下,当您最初加载页面时,表单将使用模型实例中的现有值而不是空白表单填充。

以上所有内容都可以使用Django class-based views在更少的代码行中完成,但它们隐藏了抽象层背后发生的事情,所以我认为看看Django的基本表单处理模式可能很有用。

请在此处查看renderget_object_or_404快捷方式功能的文档:
https://docs.djangoproject.com/en/dev/topics/http/shortcuts/