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

React前端无法获取Django后端未登录用户购物车数据问题排查

问题

开发电商项目时,为未认证用户实现购物车功能,采用session_id而非用户ID标识购物车。后端API文档测试正常,但前端React应用中,创建购物车功能正常,获取购物车却返回空列表。

相关代码如下:

models.py(购物车模型)

from django.db import models
from books.models import Book
from django.contrib.auth import get_user_model
from django.dispatch import receiver 
from django.db.models.signals import post_save
User = get_user_model()

class TimeStampedModel(models.Model):
    created = models.DateTimeField(db_index=True, auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    class Meta:
        abstract=True

class Cart(TimeStampedModel):
    total = models.DecimalField(max_digits=10, decimal_places=2, default=0, blank=True, null=True)
    session_id = models.CharField(max_length=100, blank=True)

class CartItem(TimeStampedModel):
    cart = models.ForeignKey(Cart, related_name='cart_items', on_delete=models.CASCADE)
    product = models.ForeignKey(Book, related_name='cart_products', on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)
    def __str__(self):
       return self.product.__str__()

views.py(创建购物车视图)

from django.shortcuts import get_object_or_404 
from rest_framework.generics import ListCreateAPIView, CreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView, RetrieveAPIView
from .serializers import CartItemSerializers, CartItemUpdateSerializers
from rest_framework import permissions, status
from rest_framework.response import Response
from rest_framework.exceptions import NotAcceptable, ValidationError, PermissionDenied

from .models import Cart, CartItem
from books.models import Book
from rest_framework.views import APIView
import uuid

# create cart view
class CartItemcreateAPI(CreateAPIView):
    serializer_class = CartItemSerializers
    permission_classes = (permissions.AllowAny,)
    def create(self, request, *args, **kwargs): 
        try:
            cart=Cart.objects.get(session_id = self.request.session['nonuser'],)#Tries to get the cart based on the users session id
        except:
            self.request.session['nonuser'] = str(uuid.uuid4())#if it doesn't exist it creates one
            cart = Cart.objects.create(session_id = self.request.session['nonuser'],)
        cart_id = cart.session_id
        cart = get_object_or_404(Cart, session_id=cart_id)
        product = get_object_or_404(Book, pk=request.data['product'])
        current_item = CartItem.objects.filter(cart=cart, product=product)
        if current_item.count()>0:
            raise NotAcceptable({'message':'item already in cart'})
        try:
            quantity = 1
        except Exception as e:
            raise ValidationError({'message':'please enter your quantity'})
        if quantity>product.quantity:
            raise NotAcceptable({'message':'ordered quantity more than available'})
        
        product.quantity-= quantity
        product.save()
        
        cart_item = CartItem(cart=cart, product=product, quantity=quantity)
        cart_item.save()
        serializer=CartItemSerializers(cart_item)
        cart.total += (product.price)*(quantity)
        cart.save()
        data = {'message': 'success',
                'data': serializer.data}
        return Response(data, status=status.HTTP_201_CREATED)

存在问题的获取购物车视图

class CartItemlistAPI(ListAPIView):
    serializer_class = CartItemSerializers
    permission_classes = (permissions.AllowAny,)
    def get_queryset(self):
        try:
            cart = Cart.objects.get(session_id = self.request.session['nonuser'],)
        except:
            self.request.session['nonuser'] = str(uuid.uuid4())
            cart =  Cart.objects.create(session_id = self.request.session['nonuser'],)
        queryset = CartItem.objects.filter(cart=cart)
        
        return queryset
分析与解决

问题核心是前后端session不共享:API文档测试时浏览器自动维护session,但React前端跨域请求未携带正确的session cookie,导致获取购物车时生成新的session_id,对应空购物车。

1. 配置跨域请求携带Cookie

  • 前端Axios配置:添加withCredentials: true,确保请求携带Cookie
    axios.defaults.withCredentials = true;
    
  • 后端Django配置:在settings.py中开启跨域允许携带Cookie:
    CORS_ALLOW_CREDENTIALS = True
    CORS_ORIGIN_WHITELIST = [
        "http://localhost:3000",  # 替换为你的React前端地址
    ]
    

2. 显式保存Session

生成新的session_id后,必须调用session.save()确保session持久化,否则新的session_id不会被返回给前端。

修改创建视图的异常处理:

except:
    self.request.session['nonuser'] = str(uuid.uuid4())
    self.request.session.save()  # 新增此行
    cart = Cart.objects.create(session_id = self.request.session['nonuser'],)

修改获取视图的异常处理:

except:
    self.request.session['nonuser'] = str(uuid.uuid4())
    self.request.session.save()  # 新增此行
    cart =  Cart.objects.create(session_id = self.request.session['nonuser'],)

3. 验证Session一致性

在两个视图中打印self.request.session.session_key和self.request.session['nonuser'],确认创建和获取请求使用的是同一个session。如果session_key不同,说明前端未正确携带Cookie。

4. 简化Session标识逻辑

可以直接使用Django自带的request.session.session_key作为购物车标识,避免自定义nonuser键的额外管理:

# 创建视图中
try:
    cart = Cart.objects.get(session_id=self.request.session.session_key)
except Cart.DoesNotExist:
    if not self.request.session.session_key:
        self.request.session.create()
    cart = Cart.objects.create(session_id=self.request.session.session_key)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 17:42:44