使用网址模式的正确方法

时间:2016-12-23 01:38:06

标签: django django-forms django-views

我创建了一个表单,通过提交将项目上传到数据库。问题是如果我按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。这是正确的方法吗?或者有一种聪明的方法可以做到这一点。

2 个答案:

答案 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>

不再需要消息显示部分