我创建了一个表单,通过提交将项目上传到数据库。问题是如果我按f5它会再次提交表单,因为URL现在不同了。
我有这两个网址模式
urlpatterns = [
url(r'(?i)^CMS/$', views.CMS, name='CMS'),
url(r'^createItem/$', views.createItem, name='createItem')
]
我的观点看起来像这样
def CMS(request):
form = itemCreateForm()
context = {
'form' : form,
'message' : 'Content Manage Site'
}
return render(request, 'CMS.html', context)
def createItem(request):
f = itemCreateForm(request.POST)
if f.is_valid():
f.save()
pass
form = itemCreateForm()
context = {
'form' : form,
'message' : 'ItemCreated!'
}
return render(request, 'CMS.html', context)
CMS.html
{% if message %}
{{ message }}
{% endif %}
<div class='newItemFields'>
<form action="{% url 'kar:createItem' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
</div>
我的表格
class itemCreateForm(ModelForm):
class Meta:
model = item
fields = ['name', 'type', 'price']
我从主页/ CMS /开始,填写表单并按提交,查看功能createItem
运行并创建对象并将其保存在数据库中。并将用户发送到主页/ CMS / createItem。现在,每当用户按f5时,createItem函数将再次运行,并将另一个对象插入到数据库中,其值与前一个相同,即使输入字段为空(也不能绕过那个)。 / p>
我还两次写form = itemCreateForm()
我认为这是可疑的?
我想要做的是在运行createItem之后,它应该将用户发送回主页/ CMS /而不是主页/ CMS / createItem。这是正确的方法吗?或者有一种聪明的方法可以做到这一点。
答案 0 :(得分:1)
在createItem函数的末尾,您将呈现页面的HTML而不是重定向。相反,你需要做
return HttpResponseRedirect(reverse('kar:index'))
您需要导入HttpResponseRedirect并反转,用于通过名称解析URL。
检查出来:https://docs.djangoproject.com/en/1.10/topics/forms/#the-view
答案 1 :(得分:1)
我想做的是在运行createItem之后,它应该发送 用户返回主页/ CMS /而不是主页/ CMS / createItem。会是 是正确的方法吗?或者有一种聪明的方法可以做到这一点。
这确实是正确而聪明的方法。让一个视图同时处理GET和POST,然后在成功提交表单后重定向。这可确保用户无法仅通过刷新重新提交表单。并且您解决了重复代码的问题。
urlpatterns = [
url(r'(?i)^$', views.index, name='index'),
url(r'^createItem/$', views.createItem, name='createItem')
]
然后合并你的观点
def createItem(request):
if request.method == 'POST':
f = itemCreateForm(request.POST)
if f.is_valid():
f.save()
return HttpResponseRedirect('/homepage/CMS/')
else :
form = itemCreateForm()
context = {
'form' : form,
'message' : 'Content Manage Site'
}
return render(request, 'CMS.html', context)
请注意,代码现在更短,当表单无效时,它会向用户提供正确的反馈。并且您无法刷新以提交两次。我们需要对模板进行一些小改动
<div class='newItemFields'>
<form action=method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
</div>
不再需要消息显示部分