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

Django项目中添加商品到购物车需刷新两次才更新HTML的问题

问题根因

  1. AJAX回调书写错误
    你在AJAX配置中写的success: RefreshPage()属于立即执行表达式,会在请求刚发出时就直接触发页面刷新,此时后端还未完成购物车数据的写入操作,第一次刷新拿到的是修改前的旧数据。等请求处理完成返回响应后,done回调中的跳转逻辑才会触发第二次刷新,此时才能拿到更新后的数据。
  2. 视图逻辑顺序存在隐患
    当前视图中先查询用户购物车数据,再处理购物车修改请求,如果后续有POST请求也需要渲染页面的场景,会直接返回旧数据,建议调整顺序。
  3. 模型设计缺陷(潜在问题)
    ItemInCart与Videogame使用一对一关联,会导致所有用户添加同一款游戏时修改同一条购物车项数据,多用户的购物车数量会互相干扰。

修复方案

1. 修正AJAX代码

删除多余的success立即执行逻辑,只保留done回调中的跳转逻辑即可:

$(".add_to_cart_button").on("click", function() {
  const csrftoken = Cookies.get('csrftoken');
  let requested_item = $(this).attr("data-assigned_product");
  $.ajax({
    method: 'POST',
    headers: {'X-CSRFToken': csrftoken},
    data: {
        "result": requested_item
    },
    dataType: "json"
  }).done(function(data) {
    if (data.success) {
      window.location.href = data.url;
    }
  })
});

2. 调整视图逻辑顺序

将购物车修改逻辑移到数据查询逻辑之前,避免后续扩展时出现数据不一致问题,同时补全缺失的模板渲染返回:

def category_view(request, selected_category):
  # 优先处理POST购物车修改请求
  requested_game_in_cart = request.POST.get('result')
  if requested_game_in_cart is not None:
    asked_videogame = Videogame.objects.get(name=requested_game_in_cart)
    client_id = request.session.get('client_id', request.META['REMOTE_ADDR'])
    current_client_object = VisitingClient.objects.get(pk=client_id)
    if ItemInCart.objects.filter(id=asked_videogame, user=current_client_object).exists():
      cart_item = ItemInCart.objects.get(id=asked_videogame)
      cart_item.amount += 1
      cart_item.save()
    else:
      cart_item = ItemInCart.objects.create(id=requested_game_in_cart, product=asked_videogame)
      current_client_object.items_in_cart.add(cart_item)
      current_client_object.save()
    return JsonResponse({
            'success': True,
            'url': '/catalog/' + selected_category + '/'
        })

  # 处理GET请求的页面渲染逻辑
  videogames_in_category = Videogame.objects.filter(category = Category.objects.get(name=selected_category))
  client_id = request.session.get('client_id', request.META['REMOTE_ADDR'])
  if not ClientExists(client_id):
    CreateClient(client_id)
  current_client_object = VisitingClient.objects.get(pk=client_id)
  UpdateClientAmountOfVisits(current_client_object)

  context = {
    'called_category': selected_category,
    'videogames': videogames_in_category,
    'items_in_cart': current_client_object.items_in_cart.all()
  }
  return render(request, '对应模板路径.html', context)

3. 模型优化建议

修改ItemInCart模型的关联关系,避免多用户数据冲突:

class ItemInCart(models.Model):
  amount = models.PositiveIntegerField(default=1)
  product = models.ForeignKey(to=Videogame, on_delete=CASCADE)
  # 新增用户关联字段,配合唯一约束保证同一用户同一游戏只有一条购物车记录
  user = models.ForeignKey(to=VisitingClient, on_delete=CASCADE)
  class Meta:
    verbose_name_plural = 'Items In Cart'
    unique_together = ['product', 'user']
  def __str__(self):
    return f"{self.user.id} - {self.product.name}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:36:04