【问题标题】:Empty QueryDict in ajax POST query - Djangoajax POST查询中的空QueryDict - Django
【发布时间】:2016-07-19 13:47:25
【问题描述】:

我在 Django 模板中使用带有数据的 ajax POST 查询:{'action':'add'},但如果我在 views.py 中打印 request.POST,它会显示在控制台 <QueryDict: {}> .

但萤火虫显示POST 302action=addaction=remove 参数!所以我不明白为什么<QueryDict: {}> 是空的。请帮忙。

附言。如果我使用 GET 它工作正常。

模板show_event.html

<form id="unfollow" {% if user not in event.users.all %}style="display:none;"{% endif %}>
    <input type="hidden" value="{{ event.id }}" name="remove">
    <button type="submit" class="btn btn-warning btn-block">{% trans "Remove from My events"%}</button>
</form>

<form id="follow" {% if user in event.users.all %}style="display:none;"{% endif %}>
    <input type="hidden" value="{{ event.id }}" name="add">
    <button type="submit" class="btn btn-primary btn-block">{% trans "Add to My events"%}</button>
</form>

    $(document).on('submit','#unfollow', function(e){
        e.preventDefault();
        $.ajax({
            type:"POST",
            url:'/event/follow/{{ event.id }}/',
            data: {'action':'remove'},
            success:function(){
                $('#unfollow').hide();
                $('#follow').show();
            }
        })
    });

    $(document).on('submit','#follow', function(e){
        e.preventDefault();
        $.ajax({
            type:"POST",
            url:'/event/follow/{{ event.id }}/',
            data: {'action':'add'},
            success:function(){
                 $('#follow').hide();
                 $('#unfollow').show();
            }
        })
    });

views.py:

def follow (request, event_id):
    event = get_object_or_404(Event, id=event_id)
    user = request.user
    print request.POST
    if request.method == 'POST':
        print "post"
        if request.POST['action'] == 'add':
            print "add"
            event.users.add(user)
            event.save()
        elif request.POST['action'] == 'remove':
            print "remove"
            event.users.remove(user)
            event.save()
    return HttpResponse('')

urls.py:

url(r'^event/follow/(?P<event_id>[0-9]+)/$', 'events.views.follow', name='follow')

【问题讨论】:

  • 500状态错误吗?该视图接受 counter_id 作为 kwarg 并且您正在传递 event_id.. 这是同一个视图吗?
  • @v1k45 抱歉,我粘贴了错误的视图,现在我编辑了我的问题。没有500错误

标签: jquery ajax django post


【解决方案1】:

编辑(第二次:修复表单标记以匹配 URL):

实际上,由于您的标记中包含完整的表单,因此有一种更简单的方法:

var submitHandler = function(event) {
    event.preventDefault();
    event.stopPropagation();

    var $form = $(this);
    var url = $form.attr( "action" );
    $.post(url, $form.serialize())
        .done(function(data) {
            if (data.following) {
                $('#follow').hide();
                $('#unfollow').show();
            } else {
                $('#follow').show();
                $('#unfollow').hide();
            }
        });
};

$(document).on('submit','#unfollow', submitHandler);
$(document).on('submit','#follow', submitHandler);

您的标记应为:

<form id="unfollow" method="POST" action="{% url 'follow' event_id=event.id %}
      {% if user not in event.users.all %}style="display:none;"{% endif %}>
    {% csrf_token %}
    <input type="hidden" value="remove" name="action">
    <button type="submit" class="btn btn-warning btn-block">{% trans "Remove from My events"%}</button>
</form>

<form id="follow" method="POST" action="{% url 'follow' event_id=event.id %}
      {% if user in event.users.all %}style="display:none;"{% endif %}>
    {% csrf_token %}
    <input type="hidden" value="add" name="action">
    <button type="submit" class="btn btn-primary btn-block">{% trans "Add to My events"%}</button>
</form>

你的 Django 代码:

@require_http_methods(['POST'])
def follow (request, event_id):
    event = get_object_or_404(Event, id=event_id)
    user = request.user
    action = request.POST.get('action', None)
    following = False
    if action == 'add':
        event.users.add(user)
        following = True
    elif action == 'remove':
        event.users.remove(user)
    else:
        return HttpResponseBadRequest('Unknown action: {}'.format(action))
    event.save()
    return JsonResponse({'following': following})

上一个答案:

根据您的 jQuery 版本,type 可能不再可用。尝试在 AJAX 配置中使用 method: "POST" 而不是 type: "POST"http://api.jquery.com/jQuery.ajax/

此外,为了使您的标记更符合您在视图和 JS 中的预期,请将method="POST" 添加到您的表单元素中。


旁注:

您可以通过get() 方法访问QueryDict 更好地处理不存在的参数,如下所示:

request.POST.get('action', None)

这将始终有效(除非request.POST 为无)。如果参数不存在,则返回默认值或第二个参数(在本例中为 None)。

request.POST['action']

如果action 不存在,这将失败并返回 KeyError。

【讨论】:

  • 感谢您的回答。现在,当我提交表单时(例如 event_id=28),我看到一个页面 http://127.0.0.1:8000/en/event/follow/28/,上面有 Unknown action: None 文本。而 querydict 现在是:&lt;QueryDict: {u'csrfmiddlewaretoken': [u'3Ze1vPqPp8QhbZ5fNXuwy39mw5rFL2cS'], u'remove': [u'action']}&gt;
  • 隐藏的输入字段混淆了valuename。我已在我的答案中修复了表单标记示例代码。
  • 太棒了!它现在可以工作了,但是提交后我看到一个空白页,上面有{"following": true}{"following": false}。在您的示例中,如何在没有任何页面刷新和重定向的情况下提交表单?
  • 我已经更新了我的答案。您需要将event.preventDefault(); 添加到您的提交处理程序(应该已经是这种情况了?它在您问题的代码中)。
  • 对不起,我不明白我应该把event.preventDefault();放在哪里?我试图将它添加到脚本中,但它仍然重定向我
猜你喜欢
  • 2014-11-05
  • 2016-02-05
  • 2020-05-26
  • 2011-02-04
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2013-04-22
  • 2012-08-14
相关资源
最近更新 更多