带有 ImageFields 的 ModelForm,如果验证错误则无法正确清除
首先是代码。 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 有关?
First the code.
The ModelForm (im1 and im2 are models.ImageField):
class TestForm(forms.ModelForm):
checkme = forms.BooleanField(required=True)
class Meta:
model = UserProfile
fields = ('im1', 'im2')
The view:
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})
The template:
<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>
The problems:
If im1 contains a valid image, and I check the clear checkbox next to it but don't check checkme and submit, the form comes back with an error saying that checkme is required. Although the form returns with the error, it appears as if im1 has been cleared. In reality it has not because if I reload the form im1 shows back up with its file and clear checkbox.
My question is how can I fix this? Is it something I am doing or is this something to do with django?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Django 的行为完全符合它应该做的。
如果请求是 POST 请求,则您的表单将绑定到
request.POST
和request.FILES
中的数据。instance=profile
只是告诉表单,如果所有验证通过,要保存到哪个特定对象。即使您的表单无效,它仍然会绑定到带有已清除图像的数据,这就是您传递给render()
的内容。首先,如果请求方法是 POST,您不应该创建第一个绑定表单:
其次,如果用户确实想要删除图像但只是错过了另一个复选框,为什么您希望用户执行两次相同的操作?
如果你真的需要 Django 以这种方式行事,我会做以下两件事之一。从 UserProfile 实例创建绑定表单,并将无效表单和新创建的表单传递给模板,并使用无效表单显示错误,使用另一个表单显示表单的其余部分:
或者我会做同样的事情,但将无效表单中的错误保存到新创建的表单中,这样您就不会到处都是
renders()
:两者都不是很好优雅的解决方案,我不肯定第二个由于我不完全熟悉 Django Forms 实现,因此甚至可以按预期工作,无需更多修改。
我不认为这样做值得。正如我之前所说,你只是在为你的用户创造更多的工作......
Django is acting exactly as it should.
If the request is a POST request, then your form is bound to the data from
request.POST
andrequest.FILES
.instance=profile
is simply telling the form what particular object to save to if all validation passes. Even if your form isn't valid, it's still bound to the data with the cleared image, and that's what you're passing torender()
.Firstly, you shouldn't be creating the first bound form if the request method is POST:
Secondly, why do you want your user to do the same exact action twice if they did indeed want to delete an image but simply missed another checkbox?
If you really need Django to act this way, I would do one of two things. Either create a bound form from an instance of UserProfile and pass both the non-valid form and the newly created form to the template and use the non-valid form for displaying the errors and the other one for displaying the rest of the form:
OR I'd do the same thing but save the errors from the non-valid form to the newly created form so you don't end up with
renders()
all over the place:Both aren't very elegant solutions and I'm not positive the second one will even work as expected without some more hacks since I'm not completely familiar with the Django Forms implementation.
I don't see that doing this is worth it. As I stated before, you're just creating more work for your user...