无法获得使用Django的jQuery Ajax提交表单

时间:2012-02-24 02:55:40

标签: jquery ajax django forms submit

我正在创建一个Django Web应用程序,其功能类似于本网站上的投票系统。

目前,当您点击upvote或downvote箭头时,我使用jQuery来处理颜色的变化和投票得分的变化(投票数)。我基本上取得了最初从数据库中提取的投票分数,并相应地加上或减去一个,并显示这个数字。我没有更新数据库中的分数,因此投票看起来与用户一致(如果其他人在用户访问网站时投票)。

我遇到了ajax部分的问题。基本上,当用户投票时,我仍然希望将upvote或downvote提交发送到服务器并更新数据库,但不要刷新页面。当我没有在ajax调用结束时添加“return false”时,我的数据库会更新,但我的页面会刷新。但是,当我在ajax调用结束时添加“return false”时,我的页面不会刷新,但数据库也不会更新。

这是我的表格:

<form method="post" class="voting-button" action="/sentence/vote/{{sentence.id}}/">
                    {% csrf_token %}
                    <input type="submit" class="upvote_on" name="upvote" value="" />
                    <p class="vote-score">{{sentence.total_votes}}</p>
                    <input type="submit" class="downvote_off" name="downvote" value="" />
                </form>

这是一个带有两个提交按钮的表单:一个用于upvote,一个用于downvote。

以下是点击upvote按钮时的javascript:

<script type="text/javascript">         
    //script to control arrows and the number of votes shown
        $("[name='upvote']").click(function(){
            if ( $(this).attr("class") == "upvote_off" ) {
                $(this).attr("class", "upvote_on");

                //If upvote is off and downvote is off
                if ( $(this).siblings("[name='downvote']").attr("class") == "downvote_off"){
                    var score = $(this).siblings(".vote-score").text();
                    scoreInt = parseInt(score)
                    scoreInt += 1;
                    $(this).siblings(".vote-score").text(scoreInt);
                } else { //if upvote is off and downvote is on
                    var score = $(this).siblings(".vote-score").text();
                    scoreInt = parseInt(score)
                    scoreInt += 2;
                    $(this).siblings(".vote-score").text(scoreInt);
                }

                $(this).siblings("[name='downvote']").attr("class", "downvote_off");

            } else {
                $(this).attr("class", "upvote_off");       

                $(this).siblings("[name='downvote']").attr("class", "downvote_off");

                var score = $(this).siblings(".vote-score").text();
                scoreInt = parseInt(score)
                scoreInt -= 1;
                $(this).siblings(".vote-score").text(scoreInt);
            }



            $.post(

            '/sentence/vote/{{sentence.id}}/',
            {
            name: "upvote",
            },

            function(response){
                $("#divText").text("hello world!");
            }
            )


        })

基本上,它的要点是upvote按钮可以有两个类别之一:“uvpote_off”或“upvote_on”,具体取决于用户是否投票。 if else语句只是为了更改这些状态​​是否正确更改。

这是我的django视图函数,表单发送到:

def vote(request, sentence_id):
p = get_object_or_404(Sentence, pk=sentence_id)

if 'upvote' in request.POST:
    try:
        v = Vote.objects.filter(voter = request.user).get(sentence=p)
        if v.score == 0:
            v.score = 1
        elif v.score == 1:
            v.score = 0
        else: #for case where v.score = -1
            v.score = 1 
        v.save()
    except Vote.DoesNotExist:
        v = Vote( voter =request.user, sentence=p, score=1)
        v.save()

elif 'downvote' in request.POST:
    try:
        v = Vote.objects.filter(voter = request.user).get(sentence=p)
        if v.score == 0:
            v.score = -1
        elif v.score == -1:
            v.score = 0
        else: #for case where v.score = 1
            v.score = -1
        v.save()
    except Vote.DoesNotExist:
        v = Vote( voter = request.user, sentence=p, score=1)
        v.save()


return HttpResponseRedirect(reverse('sentence.views.show_sentence_order', args=(p.sentence_order,)))

这究竟是什么问题?在过去的几个小时里我一直在努力解决这个问题并查看了一些教程,但无法弄清楚我做错了什么。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我从你的例子中注意到的一些事情,其中​​一些只是我对效率的看法:

def vote(request, sentence_id):
    p = get_object_or_404(Sentence, pk=sentence_id)

如果这是一个ajax调用,并且没有用于其他任何东西,则不需要get_object函数。只需获取对象,因为您知道投票对象存在,因为您已将其传入。但是,我会使用if request.is_ajax()方法,否则会提高500.

v = Vote.objects.filter(voter = request.user).get(sentence=p)

而你可以写:

v = Vote.objects.get(voter = request.user,sentence=p)

下面:

    v.save()
except Vote.DoesNotExist:
    v = Vote( voter =request.user, sentence=p, score=1)
    v.save()

你可以删除第一个v.save()并将第二个移出try除了块:

except Vote.DoesNotExist:
    v = Vote( voter =request.user, sentence=p, score=1)
v.save()

我还认为upvote和downvote几乎是一样的,你应该考虑创建一个为你实例化这种行为的类,所以你不必编写尽可能多的行。我意识到6-8听起来并不多,但这是一个很好的习惯。

这样做:     返回HttpResponseRedirect(反向('sentence.views.show_sentence_order',args =(p.sentence_order,)))

会将响应发送到其他一些URL和视图。我不确定show_sentence_order是做什么的,因为你没有发布它,但我认为它会导致刷新页面。

将ajax发送回客户端时,您只需执行以下操作:

return HttpResponse(some_object_probably_json_here, mimetype="application/json")

当然,你需要从你的javascript调用中捕获它,我无法看到你手头的那个。

我强烈建议您阅读本网站:

http://lethain.com/intro-to-unintrusive-javascript-with-django/

并逐步完成整个教程。

答案 1 :(得分:0)

好的,我终于得到了我想要的工作。我以前的代码有很多错误,一个是在$.post函数中,我传递了网址'/sentence/vote/{{sentence.id}}/'

然而,这是我应该做的:

var loadURL = $(this).parent().attr("action");
    $.ajax({
                type: "POST",
                url: loadURL,
                data: loadData,

    }); // End .ajax function

return false;   

})

因为网站上有很多表单,所以我必须从我点击的提交按钮的父级中获取网址,以确保它是正确的表单。我注意到我的请求都是“/ sentence / vote //”

后才意识到这一点

然后另一件事是关于传递CSRF令牌以及每个帖子请求,如官方Django docus所示:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

我必须承认我并不完全理解这一点,但我将代码复制到我的脚本块中,现在它正在运行。