Django项目中添加商品到购物车需刷新两次才更新HTML的问题
问题根因
- AJAX回调书写错误
你在AJAX配置中写的success: RefreshPage()属于立即执行表达式,会在请求刚发出时就直接触发页面刷新,此时后端还未完成购物车数据的写入操作,第一次刷新拿到的是修改前的旧数据。等请求处理完成返回响应后,done回调中的跳转逻辑才会触发第二次刷新,此时才能拿到更新后的数据。 - 视图逻辑顺序存在隐患
当前视图中先查询用户购物车数据,再处理购物车修改请求,如果后续有POST请求也需要渲染页面的场景,会直接返回旧数据,建议调整顺序。 - 模型设计缺陷(潜在问题)
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
相关产品推荐
相关产品推荐

