Django Serializer如何获取反向关联Allotment表的transaction_no字段
实现方案
你只需要修改视图查询集和序列化器两处代码即可,同时可以顺手修正一个不符合REST规范的状态码问题:
1. 优化视图查询(避免N+1查询问题)
修改MREmpTableAPIView的查询逻辑,提前预加载关联的Allotment数据,避免序列化时循环查询数据库:
class MREmpTableAPIView(APIView): permission_classes = (permissions.IsAuthenticated, MRViewPermission) def get(self, request, *args, **kwargs): # 新增prefetch_related预加载关联的Allotment数据 items = MaterialRequest.objects.prefetch_related('allotment_set').order_by('-id') serializer = EMaterialRequestTableListSerializer(items, many=True) # 注意:GET请求不应该返回201状态码,201是创建资源成功的返回值,这里修正为200 return Response(serializer.data, status=status.HTTP_200_OK)
2. 修改序列化器新增transaction_no字段
在EMaterialRequestTableListSerializer中新增关联字段的读取逻辑:
class EMaterialRequestTableListSerializer(serializers.ModelSerializer): owner = serializers.SlugRelatedField(read_only=True, slug_field='full_name') # 新增关联的transaction_no字段 transaction_no = serializers.SerializerMethodField() class Meta: model = MaterialRequest exclude = ('flows',) def get_transaction_no(self, obj): # 单条MaterialRequest仅对应一条Allotment,直接取第一条即可,同时兼容无关联数据的场景避免报错 allotment = obj.allotment_set.first() return allotment.transaction_no if allotment else None
可选优化(非必须)
如果想让反向查询更直观,可以修改Allotment模型的外键定义,增加related_name参数:
class Allotment(models.Model): transaction_no = models.IntegerField(default=0) # 新增related_name后,反向查询可以直接用obj.allotment.first()替代obj.allotment_set.first() sales_order = models.ForeignKey(MaterialRequest, on_delete=models.CASCADE, related_name='allotment') is_delivered = models.BooleanField(default=False) document_available = models.BooleanField(default=False)
内容的提问来源于stack exchange,提问作者Yantra Logistics
相关产品推荐
相关产品推荐

