为什么我的Django表单会从索引页面再次发布?

时间:2017-08-02 19:26:30

标签: django forms post

我是Django的新手,并且已经关注了一些印刷和在线教程,开始开发基本的Web应用程序。我已经达到了我的目的:

  • 索引页面(模板)
  • 表格(模板)
  • 基本型号
  • 处理表单的视图函数
  • 所需的网址格式

我的表单允许我输入文件名并将其保存在数据库中。表单有效,它将数据保存到数据库,用户返回索引页面。一切正常。

我的问题是:

  1. 如果我在提交表单后返回索引页面并在浏览器中点击刷新,则会尝试再次提交相同的数据,即使表单未显示。
  2. 即使我可以看到索引页面内容,浏览器地址栏中的URL仍然具有add_media表单的URL。
  3. 一切都很奇怪!这是一些代码:

    index和add_media的视图函数:

    from django.shortcuts import render
    from django.http import HttpResponse
    from django.contrib.auth.decorators import login_required
    from django.template.context_processors import request
    
    from .forms import MediaForm
    from .models import Media
    
    # Create your views here.
    @login_required
    def index(request):
    
        media_list = Media.objects.order_by('title')
        context_dict = {'media': media_list}
        return render(request, 'media/index.html', context_dict)
    
    @login_required
    def add_media(request):
        form = MediaForm()
    
        if request.method == 'POST':
            form = MediaForm(request.POST)
    
            if form.is_valid():
                form.save(commit = True)
    
                return index(request)
            else:
                print(form.errors)
    
        return render(request, 'media/add_media.html', {'form': form})
    

    以下表格:

    from django import forms
    
    from .models import Media
    
    class MediaForm(forms.ModelForm):
        media = Media
        title = forms.CharField(max_length=50)
    
        class Meta:
            # Associate the ModelForm and the Model
            model = Media
            fields = ('title',)
    

    模板:

    {% extends 'base.html' %}
    
    {% block title %}My Media Library{% endblock %}
    {% block content %}
        <a href="/media/add_media/" id="id_add_media">Add Media</a> - <a href="/account/logout" id="id_logout">Logout</a>
        <h2 name="pagename">Home Page</h2>
        <div>
        {% if media %}
        <ul>
            {% for item in media %}
                <li>
                    {{ item.title }}
                </li>
            {% endfor %}
        </ul>
        {% else %}
            <p>There is no media in the system at present</p>
        {% endif %}    
    
    
        </div>
    
    {% endblock %}
    

    add_media.html模板:

    {% extends 'base.html' %}
    
    {% block title %}Add Media{% endblock %}
    
    {% block content %}
      <h2>Add Media</h2>
      <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" value="Save Media" name="save">Save Media</button>
      </form>
    {% endblock %}
    

    网址:

    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        url(r'^$', views.index, name='index'), 
        url(r'^index/$', views.index, name='index'), 
        url(r'^add_media/$', views.add_media, name="add_media"),
        ]
    

    有人可以告诉我为什么,当我点击索引页面上的刷新(F5)时,它会尝试重新发布add_media表单吗?

    提前致谢

    大卫

1 个答案:

答案 0 :(得分:1)

成功发布请求后,您应该重定向用户,以防止重复提交表单。目前,您正在呈现索引模板,而不是重定向到索引URL。将您的观点更改为:

from django.shortcuts import redirect

@login_required
def add_media(request):
    form = MediaForm()

    if request.method == 'POST':
        form = MediaForm(request.POST)

        if form.is_valid():
            form.save(commit = True)
            return redirect('index')