Django - 我在更新对象时收到"This field is required"错误



当我尝试使用表单编辑包含图像上传的对象时,我会得到"此字段是必需的";。类似的表单可以很好地创建对象,但当我检索对象并尝试修改其他字段时,它在图像上失败了。

#-------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}}

错误消息:

肖像此字段为必填字段。

您没有更新实例,因为您从未将实例传递给应该更新它的视图。当您进行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)

因此,在url中,您应该指定要更新的对象的主键:

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]实现发布/重定向/获取模式[wiki]。这样可以避免在用户刷新浏览器


注意:通常最好使用get_object_or_404(…)[Django-doc],然后直接使用.get(…)[Django-doc]。在对象不存在的情况下,例如,由于用户自己更改了URL,get_object_or_404(…)将导致返回HTTP404NotFound响应,而使用.get(…)将导致HTTP 500服务器错误

相关内容

最新更新