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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:57:04