【问题标题】:Django - after submitting invalid form submit button upon click redirectsDjango - 在点击重定向提交无效表单提交按钮后
【发布时间】:2012-05-17 10:15:00
【问题描述】:

我有一个 django 项目,其中我有一个由 ajax 加载的 div 中的表单。

当我提交包含空字段的表单时,它会返回包含所需字段的表单。

当我再次点击提交时,它会重定向到表单的操作,而不是像我第一次提交时那样在 div 中重新加载表单并显示错误。

有人知道错误可能发生在哪里吗?我想象在我的 django 项目中的 ajax 或视图中的某个地方。

这是第二次提交返回的内容:

{"success": false, "form": "<head>\n\n</head>\n<body>\n<form action=\"/cookbook/createrecipe/\" method=\"POST\" name=\"recipeform\" id=\"createrecipeform\">\n\t<table>\n\t\t<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='c5ea952ee2144b377b375d91b0843c75' /></div>\n\t\t<tr><th><label for=\"id_name\">Name:</label></th><td><ul class=\"errorlist\"><li>This field is required.</li></ul><input id=\"id_name\" type=\"text\" name=\"name\" maxlength=\"200\" /></td></tr>\n<tr><th><label for=\"id_author\">Author:</label></th><td><ul class=\"errorlist\"><li>This field is required.</li></ul><input id=\"id_author\" type=\"text\" name=\"author\" maxlength=\"100\" /></td></tr>\n<tr><th><label for=\"id_picture\">Picture:</label></th><td><input type=\"file\" name=\"picture\" id=\"id_picture\" /></td></tr>\n<tr><th><label for=\"id_ingredients\">Ingredients:</label></th><td><ul class=\"errorlist\"><li>This field cannot be null.</li></ul><textarea id=\"id_ingredients\" rows=\"10\" cols=\"40\" name=\"ingredients\"></textarea></td></tr>\n<tr><th><label for=\"id_steps\">Steps:</label></th><td><ul class=\"errorlist\"><li>This field cannot be null.</li></ul><textarea id=\"id_steps\" rows=\"10\" cols=\"40\" name=\"steps\"></textarea></td></tr>\n<tr><th><label for=\"id_prep_time\">Prep time:</label></th><td><ul class=\"errorlist\"><li>This field is required.</li></ul><input type=\"text\" name=\"prep_time\" id=\"id_prep_time\" /></td></tr>\n<tr><th><label for=\"id_type\">Type:</label></th><td><ul class=\"errorlist\"><li>This field is required.</li></ul><select name=\"type\" id=\"id_type\">\n<option value=\"\" selected=\"selected\">---------</option>\n<option value=\"SW\">Sandwich</option>\n<option value=\"AP\">Appetizers</option>\n<option value=\"SD\">Sauces and Dressings</option>\n<option value=\"SS\">Soups and Salads</option>\n<option value=\"VG\">Vegetables</option>\n<option value=\"RG\">Rice, Grains and Beans</option>\n<option value=\"PA\">Pasta</option>\n<option value=\"BR\">Breakfast</option>\n<option value=\"MT\">Meat</option>\n<option value=\"SF\">Seafood</option>\n<option value=\"BP\">Bread and Pizza</option>\n<option value=\"DT\">Desserts</option>\n</select><input type=\"hidden\" name=\"reset_recipe\" id=\"id_reset_recipe\" /></td></tr>\n\t</table>\n\t<p><input type=\"submit\" value=\"Submit\"></p>\n</form>\n</body>"}

这是我的 ajax 代码:

<script type="text/javascript"> 
$(document).ready(function(){
    var form = $('form#createrecipeform');
    form.submit(function(e) {
    e.preventDefault();
    console.log('ajax form submission function called successfully.');
    //form = $(this);
    console.log(form)
    var serialized_form = form.serialize();
        $.ajax({ type: "POST", 
            url: $(this).attr('action'),
            data: serialized_form, 
            success: (function(data) { 
                console.log('ajax success function called successfully.');
                data = $.parseJSON(data);
                if (data.success) {
                    console.log('success');
                } else {        
                    console.log('failure');
                    var newForm = data.form;
                    form.replaceWith(newForm);  
                }
            })
        });
        return false;
    });
});
</script> 

这里是视图:(createrecipe 是表单的操作,account 是加载 ajax 的页面)

def createrecipe(request):
        print "entering createrecipeview"
        if request.method == 'POST':
            print "form is a post"
            form = RecipeForm(request.POST)
            print form.errors
            if form.is_valid():
                print "form is valid"
                form = RecipeForm(initial = {'original_cookbook' : request.user.cookbooks.all()[0]})
                form = form.save()

                t = loader.get_template('cookbook/create_form.html')
                c = RequestContext(request, {
                'form': form,
                })

                data = {
                'replace': True,
                'form': t.render(c),
                'success': True,
                }

                json = simplejson.dumps(data)
                return HttpResponse(json, mimetype='text/plain')
            else:
                print "form is invalid"
                form = RecipeForm(request.POST)
                t = loader.get_template('cookbook/create_form.html')
                c = RequestContext(request, {
                    'form':form,
                })

                data ={
                    'form': t.render(c),
                    'success': False,
                }

                json = simplejson.dumps(data)
                return HttpResponse(json, mimetype='text/plain')

def account(request):
    user = request.user
    if request.user.is_authenticated():

        cookbooks = user.cookbooks
        if cookbooks.all().exists():
            cookbook = cookbooks.all()[0]
            form = RecipeForm(initial = {'original_cookbook' : request.user.cookbooks.all()[0]})
            recipe_list = cookbook.recipes.all()
        else:
            raise Http404
    else:
        return HttpResponseRedirect('/accounts/login')
    t = loader.get_template('cookbook/account.html')
    c = RequestContext(request, {
        'form': form,
        'recipe_list': recipe_list
    })
    return HttpResponse(t.render(c))

这里是 create_form.html 模板:

<head>

</head>
<body>
<form action="{% url cookbook.views.createrecipe %}" method="POST" name="recipeform" id="createrecipeform">
    <table>
        {% csrf_token %}
        {{ form.as_table }}
    </table>
    <p><input type="submit" value="Submit"></p>
</form>
</body>

这里是包含 create_form 模板的帐户模板:

{% extends "cookbook/base.html" %}
{% load pagination_tags %}
{% load comments %}


    <h1>{{ user }}'s Cookbook</h1>

<ul>
{% block nav-cookbooks %}
<li><a class="nav-inactive" href="/cookbooks/">Cookbooks</a></li>
{% endblock %}
{% block nav-account %}
<li><a class="nav-active" href="/account/">My Cookbook</a></li>
{% endblock %}
</ul>
{% block content %}
{% autopaginate recipe_list 6 %}
    <div id="recipe_cont">
            {% for recipe in recipe_list %}
        <div class="recipe">
            <div class="button">    
            <a href="{% url cookbook.views.userrecipe recipe.id %}" style="display: none;"></a>   
            <img src="{{ STATIC_URL }}chicknbraw.jpg" alt="" height="70" width="70" style="display:inline;" />
            <h4>{{ recipe.name }}</h4>
             </div>
            <h5>{{ recipe.author }}</h5>
            <h5>Prep Time: {{ recipe.prep_time }} minutes</h5>

            <h6><a href="/addrecipe/{{ recipe.id }}">Add Recipe</a>
                <a href="/removerecipe/{{ recipe.id }}">Remove Recipe</a></h6>
        </div>
    {% endfor %}
    </div>

    <div id="popupContact" class="popup">
            <a id="popupContactClose" style="cursor:pointer;float:right;">x</a>
            <p id="contactArea">
            <h1 style="text-align:center">Create New Recipe</h1>
            {% include 'cookbook/create_form.html' %} 
            </p>
    </div>
    <div id="backgroundPopup">
    </div>  
    <div id="col2-footer">
    {% paginate %}
    <p id="recipe_order_text"> order by: <a href="/userbook/ordered/name">abc</a>|<a href="/userbook/ordered/date">date</a> 
    </div>

{% endblock %}

{% block footer %}
        <a class="create" style="cursor:pointer" >Create New Recipe</a>
{% endblock %}

很抱歉放了这么多代码,但这一切似乎都依赖于另一段代码,所以我认为所有相关代码都会有所帮助

感谢您能给我的任何帮助

凯蒂

【问题讨论】:

    标签: ajax django forms submit


    【解决方案1】:

    在您的 javascript 中,您正在劫持表单以便它通过 ajax 提交,但随后您在表单上调用 replaceWith,因此您被劫持的表单被删除并被一个新的非劫持表单替换。要解决这个问题,您可以

    1) 仅替换表单的内容 - 这应该有效,因为您只是将事件附加到表单本身而不是其子元素

    2) 将您的 js 编写为一个函数,您可以首先在初始表单上调用它,然后在通过 ajax 加载的任何新表单上调用它。

    更新:例如,

    <script type="text/javascript"> 
    $(document).ready(function(){
    
        function hijack() {
            var form = $('form#createrecipeform');
            form.submit(function(e) {
                e.preventDefault();
                console.log('ajax form submission function called successfully.');
                //form = $(this);
                console.log(form)
                var serialized_form = form.serialize();
                $.ajax({ type: "POST", 
                    url: $(this).attr('action'),
                    data: serialized_form, 
                    success: (function(data) { 
                        console.log('ajax success function called successfully.');
                        data = $.parseJSON(data);
                        if (data.success) {
                            console.log('success');
                        } else {        
                            console.log('failure');
                            var newForm = data.form;
                            form.replaceWith(newForm);
                            hijack();
                        }
                    })
                });
                return false;
            });
        };
    
        hijack();
    
    });
    </script> 
    

    【讨论】:

    • 我应该把哪个js写成函数?你的意思是我在帖子顶部写的整个 js 函数?
    • 是的,只是 form.submit(...) 调用。把它放在一个函数中,然后直接调用它,也可以在 replaceWith() 部分之后立即调用它。
    • 但我的 replaceWith() 函数包含在我的 form.submit() 中。我怎么称呼它?对不起,如果我今天有点密集 - 我刚刚完成了决赛
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 2017-04-26
    • 2016-01-11
    • 1970-01-01
    相关资源
    最近更新 更多