Django REST Framework同一视图返回商品详情与关联商品queryset问题
后端修复方案
方案1:无需修改序列化器,直接在视图拼接返回结果(更简单推荐)
你完全没必要新建序列化器,直接在视图里分别序列化商品详情和关联商品,拼到返回的字典里就行,代码如下:
@api_view(['GET']) def getProduct(request, pk): product = Product.objects.get(_id=pk) related = Product.objects.filter(category=product.category).exclude(_id=pk).order_by('?')[:4] # 分别序列化两个queryset product_data = ProductSerializer(product, many=False).data related_data = ProductSerializer(related, many=True).data # 拼接返回 return Response({ "product": product_data, "related": related_data })
这个方案不用改任何序列化器代码,逻辑更直观,后续维护也方便。
方案2:修复你原来的序列化器方案
你的序列化器错误点有3个:
product = Product.objects.all()是错误写法,当前商品就是传入的obj参数,不需要额外查询select_related('Product')无意义,你的Product模型没有叫Product的外键,会触发字段不存在报错- 重复写了两次
[:4]属于冗余代码
修复后的序列化器代码:
class ProductWithRelatedSerializer(ProductSerializer): related = serializers.SerializerMethodField(read_only=True) class Meta: model = Product fields = '__all__' def get_related(self, obj): # obj就是当前的商品对象,直接取它的category即可 related = Product.objects.filter(category=obj.category).exclude(_id=obj._id).order_by('?')[:4] return ProductSerializer(related, many=True).data
用这个方案的话,接口返回的结果里related字段是挂在商品详情对象下的。
前端修复方案
首先先确认你用的是哪个后端方案:
如果用的是方案1(推荐):
- 先修改你的
productDetailsReducer,把接口返回的product和related都存入state,确保state结构和接口返回的字段匹配。 - 修改渲染逻辑,related是数组,需要循环遍历:
你原来的<h3>{related.id}</h3>是错误的,要改成遍历渲染:
{/* 关联商品部分 */} <ListGroup.Item> <h4>推荐关联商品</h4> <Row> {related.map(relProduct => ( <Col md={6} key={relProduct._id} className="mb-2"> <Card> <Card.Img variant="top" src={relProduct.image} /> <Card.Body> <Card.Title>{relProduct.name}</Card.Title> <Card.Text>价格:৳{relProduct.price}</Card.Text> <Link to={`/product/${relProduct._id}`} className="btn btn-primary btn-sm">查看详情</Link> </Card.Body> </Card> </Col> ))} </Row> </ListGroup.Item>
如果用的是方案2:
因为related是挂在product对象下的,所以你解构的时候不能直接取related,要改成:
const {loading, error, product} = productDetails // 关联商品从product里取 const related = product?.related || []
渲染逻辑和上面的遍历逻辑一致即可。
内容的提问来源于stack exchange,提问作者Sohanur Rahman Shanto 16209570
相关产品推荐
相关产品推荐

