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.'})
额外优化点
- 复用已查询到的
asset对象,避免重复执行数据库查询,提升性能。 - 合并两次
filter调用,简化代码结构。
内容的提问来源于stack exchange,提问作者Ashti Nematian
相关产品推荐
相关产品推荐

