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

Django ViewSet如何选中指定Portfolio实例新增关联BuySell数据

报错根因

触发TypeError的核心原因是get_queryset方法返回值不符合DRF要求:self.request.user.portfolio是一对多反向关联生成的RelatedManager管理器对象,不是可被列表接口解析的QuerySet实例,框架尝试用该对象匹配查询条件时就会抛出类型错误。

问题1修复:正确获取查询集,支持指定Portfolio筛选

首先重写get_queryset方法,跨关联关系筛选当前用户有权限访问的所有买卖记录,支持通过查询参数指定单个投资组合:

def get_queryset(self):
    # 基础过滤:仅返回当前用户名下所有投资组合关联的买卖记录
    queryset = BuySell.objects.filter(portfolio__user=self.request.user)
    # 支持前端传入portfolio_id参数,筛选指定投资组合下的记录
    portfolio_id = self.request.query_params.get("portfolio_id")
    if portfolio_id:
        queryset = queryset.filter(portfolio_id=portfolio_id)
    return queryset

小提示:当前模型定义中Portfolio.user外键的related_name='portfolio'不符合命名规范,一对多反向关联建议用复数形式related_name='portfolios',后续调用user.portfolios.all()语义更清晰,避免开发时混淆。

问题2修复:向指定Portfolio新增BuySell记录

新增逻辑必须做权限校验,禁止前端越权向其他用户的投资组合写入数据,实现步骤如下:

  1. 先修改BuySellSerializer,将portfolio字段设为只读,避免前端直接传值绕过校验:
class BuySellSerializer(serializers.ModelSerializer):
    class Meta:
        model = BuySell
        fields = "__all__"
        read_only_fields = ("portfolio",)
  1. 重写create方法,先校验传入的投资组合归属,校验通过后再绑定保存:
def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    share = serializer.validated_data["share"]
    
    # 校验必传参数
    portfolio_id = request.data.get("portfolio_id")
    if not portfolio_id:
        return Response(
            {"error": "必须指定绑定的投资组合ID"}, 
            status=status.HTTP_400_BAD_REQUEST
        )
    # 校验投资组合归属,不存在或不属于当前用户直接返回404
    target_portfolio = Portfolio.objects.filter(
        id=portfolio_id, 
        user=request.user
    ).first()
    if not target_portfolio:
        return Response(
            {"error": "指定投资组合不存在或无操作权限"}, 
            status=status.HTTP_404_NOT_FOUND
        )
    
    # 保存时绑定校验通过的投资组合实例
    serializer.save(portfolio=target_portfolio)
    return Response({"data": serializer.data}, status=status.HTTP_201_CREATED)

注意:不可直接使用前端传入的portfolio_id关联保存,跳过归属校验会产生越权写入的安全漏洞。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:06:25