Django-POST方法不适用于模板中的FOR循环内创建的那些表单

时间:2018-09-25 09:40:02

标签: django

我在模板中使用一个for循环来创建与method="post"一起使用Ajax的多个表单。但是只有items_list first 元素的格式可以正常工作,其余的完全不能显示错误405 0方法不允许。我认为他们都应该以相同的方式工作。而且只是想知道这个问题是由for循环还是其他原因引起的。

cart_items.html:

<script>
    $(document).ready(function () {
        $("#remove").click(function (event) {
            event.preventDefault();
            $.ajax({
                url: '{% url "cart:remove_from_cart" %}',
                type: "POST",
                dataType: 'json',
                data: {bookID: $('#idInput').val()},
                success: function (response_data) {
                    alert('works fine')
                },
                error: function (response_data) {
                    console.log('error occurred');
                }
            });
        });
    });
</script>

{% for book in items_list %}
    <div class="items">
        <p id="title"> {{ book.book.title }}, quantity: {{ book.quantity }} </p>
        <form method="post">
            {% csrf_token %}
            <input id="idInput" value="{{ book.book.id }}" >
            <button id="remove" type="submit"> Remove</button>
        </form>
    </div>
{% endfor %}

下面的函数体中的代码仅用于测试。第一种形式成功后,我想问题不是由函数视图引起的。

购物车/views.py:

@csrf_exempt
def remove_books(request):
    cart = Cart.objects.get(user=request.user)
    if request.method == 'POST':
        passed_id = request.POST['bookID']
        secured_id = int(passed_id)
        response_data = {
            'quantity': secured_id
        }
        return JsonResponse(response_data)

1 个答案:

答案 0 :(得分:1)

<script>
    $(document).ready(function () {
        $(".remove").click(function (event) {
            // event.preventDefault();  // don't think it should be required with button type=button
            var book_id = $(this).parent().find('.idInput').val(); // find correct input box. 
            var csrf = $('input[name="csrfmiddlewaretoken"]').val(); // get csrf token in variable.
            // there are multiple ways to get csrf token, I personally like this ^^, see https://docs.djangoproject.com/en/2.1/ref/csrf/#ajax for more
            $.ajax({
                url: '{% url "cart:remove_from_cart" %}',
                type: "POST",
                dataType: 'json',
                data: {
                    bookID: book_id,
                    csrfmiddlewaretoken: csrf // add csrf token to post data
                },
                success: function (response_data) {
                    alert('works fine')
                },
                error: function (response_data) {
                    console.log('error occurred');
                }
            });
        });
    });
</script>

{% csrf_token %} <!-- It will render a hidden input field with csrf token in it. Keep it outside for loop but in html. No need to render exactly same element multiple times. -->
{% for book in items_list %}
    <div class="items">
        <p class="title"> {{ book.book.title }}, quantity: {{ book.quantity }} </p>
        <form method="post">
            <input class="idInput" value="{{ book.book.id }}" > <!-- use class not id -->
            <button class="remove" type="button"> Remove</button> <!-- you can use button type=button to avoid form submit and hence avoid event.preventDefault(); in js -->
        </form>
    </div>
{% endfor %}