当我尝试使用表单编辑包含图像上传的对象时,我得到“此字段为必填”。类似的形式可以很好地创建对象,但是当我检索对象并尝试修改其他字段时,它在图像上会失败。
#-------models.py:
class Star(models.Model):
firstname = models.CharField(max_length=32)
lastname = models.CharField(max_length=32, blank=True)
portrait = models.ImageField(upload_to='images/')
#------views.py:
class StarForm(forms.ModelForm):
class Meta:
model = Star
fields = ["firstname", "lastname", "portrait"]
def staredit(request, star_id):
instance = Star.objects.get(pk=star_id)
form = StarForm(request.POST or None, instance=instance)
context = {
"form": form,
}
return render(request, "stars/edit.html", context)
def starchange(request):
form = StarForm(request.POST, request.FILES)
if form.is_valid():
newstar.save()
context = {
"message": "The form was posted",
}
return render(request, "stars/edit.html", context)
else:
context = {
"message": form.errors,
}
return render(request, "stars/edit.html", context)
#-----edit.html
<form action="/starchange" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{{message}}
错误消息:
肖像 此字段为必填。
答案 0 :(得分:0)
您不是要 更新实例,因为您从未将实例传递给应该更新实例的视图。进行POST要求时,浏览器仅提交表单元素的内容。没有有关呈现先前表单的数据,该数据会丢失。
您应指定instance
进行更新,因此:
from django.shortcuts import get_object_or_404
def starchange(request, pk):
obj = get_object_or_404(Star, pk=pk)
form = StarForm(request.POST, request.FILES, instance=obj)
if form.is_valid():
form.save()
context = {
"message": "The form was posted",
}
return render(request, "stars/edit.html", context)
else:
context = {
"message": form.errors,
}
return render(request, "stars/edit.html", context)
在网址中,因此您应指定要更新的对象的主键:
urlpatterns = [
# …,
path('starchange/<int:pk>/', views.starchange, name='starchange')
]
在模板中,您应该向具有给定实例的视图发出POST请求:
<form action="{% url 'starchange' pk=form.instance.pk %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
这是为什么相同视图经常用于GET和POST请求的主要原因之一,因为它消除了很多重复的逻辑。此外,它也更干净:您可以使用GET检索页面,并使用POST提交页面。
注意:如果POST请求成功,则应进行
redirect
[Django-doc] 实现Post/Redirect/Get pattern [wiki]。 这样可以避免在用户刷新页面时发出相同的POST请求。 浏览器。
注意:通常最好使用
get_object_or_404(…)
[Django-doc], 然后直接使用.get(…)
[Django-doc]。如果对象不存在, 例如,由于用户自己更改了网址,因此get_object_or_404(…)
将导致返回 HTTP 404 Not Found 响应,而使用.get(…)
将导致 HTTP 500服务器错误。