【发布时间】:2020-02-10 14:33:51
【问题描述】:
我有一个标准表单来编辑其中包含文件字段的对象。当我添加一个新的配置文件时,一切正常,但是当我想修改一个字段时,就会出现问题:当我不包含 request.FILES 时,所有字段都会在表单中检索并且可以毫无问题地更新,除了头像(文件字段),但是当我添加 request.FILES 时,不再在输入中检索字段,并且表单无效。我做错了什么?
models.py:
from django.db import models
class Profile(models.Model):
name = models.CharField(max_length=45)
email = models.EmailField()
avatar = models.FileField(upload_to="avatars/")
def __str__(self):
return self.name
forms.py:
from django import forms
from .models import Profile
class EditUserForm(forms.ModelForm):
class Meta:
model = Profile
fields = ["name", "email", "avatar"]
profile.html:
<form method="POST">
{% csrf_token %}
<div class="col-md-12">
<div class="row border m-3 p-5">
<div class="col-md-6">Name</div>
<div class="col-md-6">{{ form.name }}</div>
</div>
<div class="row border m-3 p-5">
<div class="col-md-6">Email</div>
<div class="col-md-6">{{ form.email }}</div>
</div>
<div class="row border m-3 p-5">
<div class="col-md-6">Avatar</div>
<div class="col-md-6">
<img src="{{ profile.avatar.url }}" width="100rem" />
{{ form.avatar }}
</div>
</div>
<div class="row">
<button type="submit" class="btn btn-success">Save</button>
</div>
</div>
</form>
views.py:
def profile(request, pk):
profile_instance = Profile.objects.get(id=pk)
form = EditUserForm(request.POST, request.FILES, instance = profile_instance)
context = {
'profile': profile_instance,
'form': form,
}
if request.method == "POST":
if form.is_valid():
profile = form.save(commit=False)
profile.save()
else:
print("form not valid")
else:
return render(request, "app/profile.html", context)
return render(request, "app/profile.html", context)
【问题讨论】:
-
首先,您需要将 (html) 表单的 enctype 设置为“multipart/form-data”(参见docs.djangoproject.com/en/3.0/topics/http/file-uploads),否则
request.FILES将为空。然后,您希望在模板中实际显示表单的验证错误。最后,您应该始终在成功发布后重定向(post-redirect-get 模式),以防止重复提交。 -
现在可以使用了,谢谢。不,我已经在代码中使用了 enctype,但问题是返回渲染,我将其更改为重定向并且它起作用了。但是,表单中没有填充前 2 个字段(姓名和电子邮件)。
-
如果是
GET请求,您应该不用数据实例化您的表单。这是因为如果您传递数据(通过传递request.POST来完成)并且数据为空,则您的表单被绑定并且初始值被设置为数据值。请按照example 中所示的方式完全 进行操作:在GET请求的情况下实例化EditUserForm(instance=...)。并且仅在表单有效的情况下重定向。
标签: django django-forms