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

Django视图多对多字段报错:关联前需先保存对象获取ID

问题分析与解决

错误翻译

return (<PaperTrading: PaperTrading object (None)> 需要先为字段“id”赋值,才能使用这个多对多关系。
)

问题原因

你在创建PaperTrading对象时,直接链式调用.assets.set()方法,并且把这个方法的返回值(None)赋值给了queryset变量。虽然create()方法会将对象保存到数据库并生成id,但链式调用的写法会导致操作多对多关系时出现异常,同时错误覆盖了queryset的初始值。

修正后的代码

# -------------------- Create Paper_Trading View --------------------

class CreatePaperTradingApiView(viewsets.GenericViewSet):
    permission_classes = (IsAuthenticated,)
    serializer_class = PaperTradingSerializer

    """
    create a paper_trading for request.user
    """
    @action(methods=['POST'], detail=True, url_name='paper', url_path='paper')
    def create_paper_trading(self, request, pk=None):
        data = request.data
        asset = Assets.objects.get(id=pk)
        symbol = asset.core_key
        user_id = request.user.pk

        # 检查是否已有相同资产的未平仓模拟交易
        if not PaperTrading.objects.filter(
            user_id=user_id, 
            status='OPENED',
            assets__core_key=symbol
        ).exists():
            # 先创建PaperTrading对象
            paper_trade = PaperTrading.objects.create(
                user_id=user_id,
                average_price=data['average_price'],
                quantity=data['quantity'],
                status='OPENED',
                side=data['side']
            )
            # 单独设置多对多关联
            paper_trade.assets.set([asset])  # 复用已查询的asset对象,减少重复数据库操作

            # 查询刚创建的交易记录
            queryset = PaperTrading.objects.filter(
                user_id=user_id, 
                status='OPENED',
                assets__core_key=symbol
            )
            serializer = PaperTradingSerializer(queryset, many=True)
            return Response(serializer.data)
        
        return Response(data={'result': 'This symbol opened.'})

额外优化点

  1. 复用已查询到的asset对象,避免重复执行数据库查询,提升性能。
  2. 合并两次filter调用,简化代码结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:48:20