Django DRF创建Abs模型实例后获取实例并生成关联Esc数据的问题
实现方案
问题核心原因
- DRF 中
ModelViewSet的create方法返回值是响应对象,不是你创建的Abs模型实例,所以直接传返回值res会报错 filter()方法返回的是查询集,不是单个模型实例,就算只有一条匹配数据也需要调用.first()才能拿到实例,而且通过非主键字段过滤可能存在重复匹配的问题
最优实现代码
你可以拆分默认 create 方法的执行逻辑,直接从序列化器的保存操作拿到新创建的实例:
from rest_framework import status from rest_framework.response import Response class AbsView(viewsets.ModelViewSet): def create(self, request, *args, **kwargs): # 先执行序列化参数校验,和默认逻辑保持一致 serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) # 保存后直接返回新创建的Abs实例 abs_instance = serializer.save() # 用实例直接创建Esc记录 Esc.objects.create(user=request.user, detail_parts=abs_instance) # 构造标准返回响应 headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
兼容原有写法的方案
如果你不想修改原有 super().create() 的调用逻辑,也可以从返回的响应数据中提取新实例的主键,再查询得到实例:
class AbsView(viewsets.ModelViewSet): def create(self, request, *args, ** kwargs): res = super().create(request, *args, ** kwargs) # 从响应数据中获取新生成的Abs主键 new_abs_id = res.data['id'] # 主键查询得到唯一实例 abs_instance = Abs.objects.get(id=new_abs_id) Esc.objects.create(user=request.user, detail_parts=abs_instance) return res
额外注意
外键字段支持两种赋值方式:
- 直接传模型实例:
detail_parts=abs_instance - 传主键值,字段名加
_id后缀:detail_parts_id=new_abs_id
内容的提问来源于stack exchange,提问作者ira
相关产品推荐
相关产品推荐

