You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

网站Wishlist功能报错:int()参数为NoneType的排查与解决

解决心愿单功能中TypeError:int()参数为NoneType的问题

问题概述

开发网站心愿单功能时触发如下错误:

TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

经排查,views.py中通过request.POST.get('product_id')获取的product_id为None,核心原因是前端wishlist.js未能正确获取商品ID。

问题根源分析

  1. 前端DOM结构问题:.add-wishlist按钮和.prod_id隐藏输入框分属不同的col-lg-4容器,而.data_product是独立空容器,导致$(this).closest('.data_product').find('.prod_id').val()无法定位到目标元素,返回None。
  2. 后端代码笔误:WishList.objects.filet应为filter;Product.objects.get()未捕获商品不存在的异常,且未处理product_id为空的情况。

修复方案

1. 修正前端JS获取product_id逻辑(最简可靠方案)

直接从按钮的data-product属性取商品ID,无需依赖隐藏输入框:

$(document).ready(function(){
    $('.add-wishlist').click(function(e){
        e.preventDefault();

        var product_id = $(this).data('product'); // 直接读取按钮的data-product属性
        var token = $('input[name=csrfmiddlewaretoken]').val();
        
        $.ajax({
            method:"POST",
            url:"/add-wishlist",
            data:{
                'product_id': product_id,
                csrfmiddlewaretoken: token
            },
            success: function(response){
                alertify.success(response.status)
            }
        });
    });
});

2. 修复后端views.py的错误

  • 增加product_id空值、格式校验
  • 修正filet为filter
  • 捕获商品不存在的异常:
@csrf_exempt
def addwishlist(request):
    if request.method == 'POST':
        if request.user.is_authenticated:
            prod_id_str = request.POST.get('product_id')
            # 校验product_id是否为空
            if not prod_id_str:
                return JsonResponse({'status':"无效的商品ID"})
            # 校验格式是否为整数
            try:
                prod_id = int(prod_id_str)
            except ValueError:
                return JsonResponse({'status':"商品ID格式错误"})
            
            # 检查商品是否存在
            try:
                product_check = Product.objects.get(id=prod_id)
            except Product.DoesNotExist:
                return JsonResponse({'status':"该商品不存在"})
            
            # 检查是否已在心愿单
            if WishList.objects.filter(user=request.user, product=product_check).exists():
                return JsonResponse({'status':"商品已在心愿单中"})
            else:
                WishList.objects.create(user=request.user, product=product_check)
                return JsonResponse({'status':"商品已添加至心愿单"})
        else:
            return JsonResponse({'status':"请登录后操作"})
    return redirect('/')

3. 可选:调整HTML结构(若坚持用隐藏输入框)

将.data_product改为包裹两个col-lg-4的父容器,确保DOM查找路径正确:

{% extends 'customertemplates/main.html' %}
{% load static %}
{% block content %}
<div class="row">
    <!-- 修改:让data_product包裹两个商品列 -->
    <div class="container py-5 data_product">
        <div class="col-lg-4" style="float:left;">
            <img class="thumbnail" src="{{product.imageURL}}">
            <button style="width:375px" data-product="{{product.id}}" data-action="add" class="btn btn-outline-secondary add-btn update-cart">Add to Cart</button>
            <br>
            {% if user.is_authenticated and user.is_customer %}
            <button style="width:375px" data-product="{{product.id}}" data-action="add" class="btn btn-outline-secondary add-btn add-wishlist"><i class="fa fa-heart">Add to Wishlist</i></button>
            {% else %}
            <button style="width:375px" data-product="{{product.id}}" data-action="add" class="btn btn-outline-secondary add-btn"><a href="{% url 'customer_login' %}" class="ml-2"><i class="fa fa-heart">Add to Wishlist</i></a></button>
            {% endif %}
        </div>
        <div class="col-lg-4">
            <input type="hidden" value="{{product.id}}" class="prod_id">
            <!-- 其他商品信息不变 -->
        </div>
    </div>
</div>
{% endblock content %}

验证步骤

  1. 点击"Add to Wishlist"按钮,查看浏览器控制台的Network请求,确认product_id参数已正确传递。
  2. 测试场景:未登录用户操作、添加不存在的商品、重复添加商品,验证返回的状态提示是否符合预期。

内容的提问来源于stack exchange,提问作者Shatila Shahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 22:30:53