django - Django - POST 方法不适用于在模板中的 FOR 循环中创建的表单
问题描述
我在模板中使用 for 循环来创建多个method="post"
与 Ajax 一起使用的表单。但只有第一个元素的表单items_list
可以正常工作,其余的根本不工作,显示错误 405 0 Method Not Allowed。我认为他们都应该以同样的方式工作。只是想知道这个问题是由 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)
解决方案
<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 %}
推荐阅读
- whatsapp - 什么可能导致我的 WhatsApp 贴纸包无法工作?
- data-structures - 数据结构:什么是 T 表?
- react-native - React Native 月份和年份选择器
- java - 在 Java 中使用 HttpURLConnection POST
- c++ - 如何使用 OpenCV 将 RBG 图像转换为 HSV 并将 H、S 和 V 值保存到 C++ 中的 3 个单独的图像中?
- android - TouchableOpacity onLongPress 拦截 FlatList 滚动
- gspread - 更新 gspread 以获取 duplicate_sheet
- java - 连接未与托管连接关联
- robotframework - 如何从机器人框架代码之间的全局变量中获取值
- c++ - OpenCV EqualizeHist() 从彩色图像创建黑白图像