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

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个:

  1. product = Product.objects.all()是错误写法,当前商品就是传入的obj参数,不需要额外查询
  2. select_related('Product')无意义,你的Product模型没有叫Product的外键,会触发字段不存在报错
  3. 重复写了两次[: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(推荐):

  1. 先修改你的productDetailsReducer,把接口返回的product和related都存入state,确保state结构和接口返回的字段匹配。
  2. 修改渲染逻辑,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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:15:02