Ajax-запрос не работает должным образом в Django - PullRequest
0 голосов
/ 24 июня 2018

JS-код для AJAX-запроса

<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>

updateapi в views.py:

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 это происходит альтернативно.

Не знаю, почему у меня такое странное поведение.

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

Это нормально, так как это токен 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',
 ....
})

у меня сработало

0 голосов
/ 24 июня 2018

Это потому, что вам нужно настроить CSRF в вашем запросе AJAX, так же, как в обычном запросе.

Добавьте следующий код в ваш 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

Надеюсь, это поможет.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...