【问题标题】:Get reverse relation in Django Serializer在 Django Serializer 中获取反向关系
【发布时间】:2021-11-16 12:50:06
【问题描述】:

型号:

class MaterialRequest(models.Model):

    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='owner')
    linked = models.CharField(max_length=50, default="-", blank=True, null=True)
    flows = models.ManyToManyField(MaterialRequestFlow)
    is_allocated = models.BooleanField(default=False)
    delivery_required_on = models.DateTimeField(default=datetime.now)
    raised_by = models.CharField(max_length=1000, default="__________", blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

class Allotment(models.Model):

    transaction_no = models.IntegerField(default=0)
    sales_order = models.ForeignKey(MaterialRequest, on_delete=models.CASCADE)
    is_delivered = models.BooleanField(default=False)
    document_available = models.BooleanField(default=False)

现在要显示我的材料请求表,我正在做这样的事情:

class MREmpTableAPIView(APIView):
    permission_classes = (permissions.IsAuthenticated, MRViewPermission)

    def get(self, request, *args, **kwargs):
        items = MaterialRequest.objects.all().order_by('-id')
        serializer = EMaterialRequestTableListSerializer(items, many=True)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

序列化器:

class EMaterialRequestTableListSerializer(serializers.ModelSerializer):

    owner = serializers.SlugRelatedField(read_only=True, slug_field='full_name')

    class Meta:
        model = MaterialRequest
        exclude = ('flows',)

我在哪里获得材料请求的所有详细信息,但我还想在材料请求表中显示linked 分配的transaction_no。我该怎么做?

编辑:

单个物料请求与单个分配(transaction_no)链接,我想在同一张桌子上显示Transaction no

我得到的输出:

created_at: "2021-09-22T10:28:44.248034Z"
delivery_required_on: "2021-09-22T09:08:43.968000Z"
id: 739
is_allocated: false
linked: "729-3"
owner: "Lumax Mannoh Allied Technologies Limited"

期望的输出:

created_at: "2021-09-22T10:28:44.248034Z"
delivery_required_on: "2021-09-22T09:08:43.968000Z"
id: 739
is_allocated: false
linked: "729-3"
owner: "Lumax Mannoh Allied Technologies Limited"
transaction_no: foo

【问题讨论】:

  • 你能分享你的序列化器吗?您需要MaterialRequest 中的Allotment transaction_no 中的哪一个?全部?
  • @BrianD 我已经用序列化程序更新了问题,我想显示每个材料请求的transacation_no
  • OK 每个材料请求可以有多个Allotments,因此您最终会得到一个交易编号列表。您能否分享您正在寻找的示例输出?
  • @BrianD 在这种情况下,我想拥有列表的第一个元素,如果已经存在,代码通常会阻止用户创建分配......所以这可能不是问题

标签: django django-models django-rest-framework django-queryset


【解决方案1】:

解决此问题的一种直接方法是使用SerializerMethodField,如下所示:

class EMaterialRequestTableListSerializer(serializers.ModelSerializer):
    owner = serializers.SlugRelatedField(read_only=True, slug_field='full_name')
    transaction_no = serializers.SerializerMethodField()

    class Meta:
        model = MaterialRequest
        exclude = ('flows',)

    def get_transaction_no(self, obj)
        allotment = obj.allotment_set.first()
        return allotment.transaction_no if allotment else None

但这将尝试访问每个MaterialRequest 实例的数据库,以获取相关的分配。

为了提高效率,您可以像这样预取每个材料请求的相关分配:

items = MaterialRequest.objects.all().order_by('-id').prefetch_related('allotment_set')

然后在你的序列化器中做这样的事情:

class EMaterialRequestTableListSerializer(serializers.ModelSerializer):
    owner = serializers.SlugRelatedField(read_only=True, slug_field='full_name')
    transaction_no = serializers.SerializerMethodField()

    class Meta:
        model = MaterialRequest
        exclude = ('flows',)

    def get_transaction_no(self, obj)
        if obj.allotment_set.all():
            return obj.allotment_set.all()[0].transaction_no
        return None

【讨论】:

    猜你喜欢
    • 2013-10-20
    • 2020-04-24
    • 2017-02-21
    • 2014-05-27
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    相关资源
    最近更新 更多