Django 5视图无法接收JS发送的POST请求,product_id为None
问题:Django 5添加购物车接口触发DoesNotExist错误
访问/cart/cart_add时出现DoesNotExist异常,原因是执行product = Products.objects.get(id=product_id)时product_id为None,从request.POST中获取的product_id同样是None。该代码在Django 4中正常运行,升级到Django 5后出现问题,怀疑是JavaScript代码存在错误。
相关代码
jquery-ajax.js
$(document).ready(function () { var successMessage = $("#jq-notification"); $(document).on("click", ".add-to-cart", function (e) { e.preventDefault(); var goodsInCartCount = $("#goods-in-cart-count"); var cartCount = parseInt(goodsInCartCount.text() || 0); var product_id = $(this).data("product-id"); var add_to_cart_url = $(this).attr("href"); $.ajax({ type: "POST", url: add_to_cart_url, data: { product_id: product_id, csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(), }, success: function (data) { successMessage.html(data.message); successMessage.fadeIn(400); setTimeout(function () { successMessage.fadeOut(400); }, 7000); cartCount++; goodsInCartCount.text(cartCount); var cartItemsContainer = $("#cart-items-container"); cartItemsContainer.html(data.cart_items_html); }, error: function (data) { console.log("text"); }, }); });
catalog.html
<a href="{% url "cart:cart_add" %}" class="btn add-to-cart" data-product-id="{{ product.id }}"> {% csrf_token %} <img class="mx-1" src="{% static "deps/icons/cart-plus.svg" %}" alt="Catalog Icon" width="32" height="32">
views.py
def cart_add(request): product_id = request.POST.get("product_id") product = Products.objects.get(id=product_id) user_cart = get_user_carts(request) cart_items_html = render_to_string( "carts/includes/included_cart.html", {'carts': user_cart}, request=request ) response_data = { 'masage': 'Тext', 'cart_items_html': cart_items_html, } return JsonResponse(response_data)
排查与修复步骤
验证前端数据渲染与获取
- 点击"加入购物车"按钮前,打开浏览器控制台(F12),在JS代码的
var product_id = $(this).data("product-id");下方添加console.log(product_id);,查看控制台输出是否为有效产品ID。若输出undefined,说明前端未正确读取属性值。 - 查看页面源代码,确认a标签的
data-product-id属性是否正确渲染出产品ID(如data-product-id="1"),而非空值。Django 5模板渲染更严格,需确保{{ product.id }}对应的对象存在且id属性有效。
- 点击"加入购物车"按钮前,打开浏览器控制台(F12),在JS代码的
修复前端属性读取逻辑
- 若
.data("product-id")读取失败,改用$(this).attr("data-product-id")直接获取字符串形式的属性值,避免jQuery自动类型转换带来的潜在问题。
- 若
后端增加参数校验与容错
- 即使前端修复,后端也需添加校验逻辑,避免直接调用
get()抛出异常:def cart_add(request): product_id = request.POST.get("product_id") # 校验产品ID是否存在 if not product_id: return JsonResponse({'message': '缺少产品ID'}, status=400) # 捕获产品不存在异常 try: product = Products.objects.get(id=product_id) except Products.DoesNotExist: return JsonResponse({'message': '产品不存在'}, status=404) # 原有逻辑 user_cart = get_user_carts(request) cart_items_html = render_to_string( "carts/includes/included_cart.html", {'carts': user_cart}, request=request ) # 修正拼写错误:masage → message response_data = { 'message': '成功加入购物车', 'cart_items_html': cart_items_html, } return JsonResponse(response_data)
- 即使前端修复,后端也需添加校验逻辑,避免直接调用
修正CSRF令牌位置
catalog.html中{% csrf_token %}被放在a标签内部,这是无效的HTML结构(a标签不能包含表单元素),会导致jQuery无法正确获取令牌值。将{% csrf_token %}移到a标签外部,或包裹在<form>标签内,确保$("[name=csrfmiddlewaretoken]")能定位到对应的隐藏输入框。
内容的提问来源于stack exchange,提问作者Максим Шолох
相关产品推荐
相关产品推荐

