Ajax 请求在 Django 中无法正常工作

Posted

技术标签:

【中文标题】Ajax 请求在 Django 中无法正常工作【英文标题】:Ajax request not working properly in django 【发布时间】:2018-12-03 01:20:47 【问题描述】:

ajax请求的JS代码

<script type="text/javascript">
    $(document).ready(function()
        console.log("IN")
        var cartUpdateForm = $('.js_cart_update_form')
        cartUpdateForm.submit(function(event)
            event.preventDefault()
            var thisform    = $(this);
            var method      = thisform.attr("method");
            var api         =  thisform.attr("api");
            var data_       = thisform.serialize();
            var current     = window.location.href
            console.log(method,api,current,data_)
            $.ajax(
                url:api,
                data:data_,
                type:method,
                success:function(data)
                    console.log("success")
                    console.log(data)
                    update_table(data)
                ,
                error:function(data)
                    console.log('error')
                

            );
                 function update_table(data)
                    table_ = $('.js_cart_table')
                    table_body_ = table_.find(".js_cart_body")
                    table_body_.html("")
                    remove_form = $(".js_remove_form")
                    if(data.items.length > 0)
                        $.each(data.items , function(index , val)
                            var rmf = remove_form.clone()
                            rmf.css('display','block')
                            rmf.find(".cart_item_id").val(val.id)
                            table_body_.prepend("<tr><td>"+val.name+"</td> 
<td>"+val.price+"</td><td>"+rmf.html()+"</td></tr>")
                        );
                    
                    else
                    
                        console.log("reloading..")
                        window.location.href = current
                    
                
            );
        );
    </script>

views.py 中的更新api:

def update_util(request):
    pk = int(request.POST.get('item_id'))
    rest_id  = request.session['rest_id']
    restaurant = Restaurant.objects.get(pk = rest_id)
    cart_obj = Cart.objects.new_or_create(request)
    remove = request.POST.get('remove')
    item = FoodItem.objects.get(pk=pk)
    # print(pk)
    if remove == '1': 
        cart_obj.items.remove(item)
    else:
        cart_obj.items.add(item)

def update(request):
    update_util(request)
    rest_id  = request.session['rest_id']
    return redirect(reverse('restaurant:menu', kwargs='pk':rest_id))

def updateapi(request):
    if request.is_ajax():
        update_util(request)
        cart_obj = Cart.objects.new_or_create(request)
        print(request.POST.get('remove') ,'called')
        items = []
        data = 
        for item in cart_obj.items.all():
            items.append('name':item.name , 'price':item.price 
,'id':item.id)
        data_ = 'items':items , 'total':cart_obj.total , 
'subtotal':cart_obj.subtotal
    return JsonResponse(data_)

正在调用删除的 HTML 表单:

<table class="table js_cart_table">
<thead>
    <th>Item</th><th>Price</th><th></th>
</thead>
<tbody class="js_cart_body">
    % for item in cart.items.all %
            <tr><td> item </td> <td>    item.price  </td>
                <td>% include 'cart/include/remove_cart.html' with 
 item_id=item.id %</td>
            </tr>
    % endfor %
</tbody>

    </table>
    <div class="js_remove_form" style="display: none;">
    % include 'cart/include/remove_cart.html' %</div>
 </div>

remove_cart.html:

<form class='js_cart_update_form' api="% url 'cart:update_api' %" action=" 
% url 'cart:update' %"  method='POST'>
    % csrf_token %
    <input class='cart_item_id' type="hidden" name="item_id" value= " 
item_id ">
    <input type="hidden" name="remove" value="1">
    <input class=" btn btn-xs btn-danger js_update" type='submit' value="X">
</form>

同样是add,只是remove的隐藏值是0,输入类型submit的值是Add。

购物车中的商品是正常添加的,但是当页面第一次重新加载和第二次发生 ajax 调用时删除它们时,这种情况会交替发生。

不知道我为什么会有这种奇怪的行为。

【问题讨论】:

【参考方案1】:

这是正常的,是因为CSRF令牌。 试试这个:

var csrftoken = $('[name="csrfmiddlewaretoken"]').val();

然后在你的 Ajax 请求中包含这个

$.ajax(
 ...
 headers: 
    'Accept': 'application/json', //if json
    'Content-Type': 'application/json', //if json
    "X-CSRFToken": csrftoken
    ,
    credentials: 'include',
 ....
)

它对我有用

【讨论】:

【参考方案2】:

这是因为您需要在 AJAX 请求中设置 CSRF,就像在正常请求中一样。

将以下代码添加到您的 JavaScript:

// This handles generation of CSRF token
function getCookie(name) 
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') 
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) 
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) 
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            
        
    
    return cookieValue;

$.ajaxSetup(
    beforeSend: function(xhr, settings) 
        if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) 
            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        
    
);

参考文档:https://docs.djangoproject.com/en/2.0/ref/csrf/#ajax

我希望这会有所帮助。

祝你好运!

【讨论】:

以上是关于Ajax 请求在 Django 中无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

在 django 中使用 ajax 时无法发布

Rails3 中的 Ajax 请求,无法正常工作

在 Laravel 中调用 ajax 后数据表无法正常工作

在 Django 中返回 AJAX 请求的表单错误

AJAX 调用的 Laravel 路由无法正常工作

如果查询匹配,则使用 Django 在 Ajax 调用后重定向