0

首先是代码。ModelForm(im1 和 im2 是 models.ImageField):

class TestForm(forms.ModelForm):
    checkme = forms.BooleanField(required=True)

    class Meta:
        model = UserProfile
        fields = ('im1', 'im2')

风景:

def test(request):
    profile = request.user.get_profile()
    form = TestForm(instance=profile)
    if request.method == "POST":
        form = TestForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            form.save()
    return render(request, 'test.html', {'form':form})

模板:

<html>
<head>
<title>Test</title>
</head>
<body>
<form method="post" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="submit" />
</form>
</body>
</html>

问题:

如果 im1 包含有效图像,并且我选中了它旁边的清除复选框,但没有选中 checkme 并提交,则表单返回一个错误,指出需要 checkme。尽管表单返回错误,但看起来好像 im1 已被清除。实际上它没有,因为如果我重新加载表单 im1 显示备份其文件并清除复选框。

我的问题是我该如何解决这个问题?这是我正在做的事情还是与 django 有关?

4

1 回答 1

0

Django 完全按照它应该的方式行事。

如果请求是 POST 请求,那么您的表单将绑定到来自request.POST和的数据request.FILESinstance=profile如果所有验证都通过,只是告诉表单要保存哪个特定对象。即使您的表单无效,它仍然会绑定到带有已清除图像的数据,这就是您要传递给render().

首先,如果请求方法是 POST,则不应创建第一个绑定表单:

def test(request):
    profile = request.user.get_profile()
    if request.method == "POST":
        form = TestForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            form.save()
    else:
        form = TestForm(instance=profile)
    return render(request, 'test.html', {'form':form})

其次,如果他们确实想要删除图像但只是错过了另一个复选框,为什么您希望您的用户执行两次相同的操作?

如果你真的需要 Django 这样做,我会做两件事之一。从 UserProfile 的实例创建一个绑定表单,并将无效表单和新创建的表单都传递给模板,并使用无效表单来显示错误,另一个用于显示表单的其余部分:

def test(request):
    profile = request.user.get_profile()
    if request.method == "POST":
        errors_form = TestForm(request.POST, request.FILES, instance=profile)
        if errors_form.is_valid():
            errors_form.save()
            form = errors_form
        else:
            form = TestForm(instance=profile)
            return render(request, 'test.html', {'form':form, 'errors_form': errors_form})
    else:
        form = TestForm(instance=profile)
    return render(request, 'test.html', {'form':form})

或者我会做同样的事情,但将错误从无效表单保存到新创建的表单,这样你就不会renders()到处都是:

def test(request):
    profile = request.user.get_profile()
    if request.method == "POST":
        errors_form = TestForm(request.POST, request.FILES, instance=profile)
        if errors_form.is_valid():
            errors_form.save()
            form = errors_form
        else:
            form = TestForm(instance=profile)
            #this is left up to you to implement, but you'd do something like
            #form.errors = errors_form.errors
            #and also iterate through every form attribute.errors and assign it to
            #errors_form attribute.errors etc...
    else:
        form = TestForm(instance=profile)
    return render(request, 'test.html', {'form':form})

两者都不是非常优雅的解决方案,我不肯定第二个解决方案甚至可以按预期工作而无需更多黑客攻击,因为我并不完全熟悉 Django Forms 实现。

我不认为这样做是值得的。正如我之前所说,你只是在为你的用户创造更多的工作......

于 2011-09-06T20:40:31.413 回答