如何习惯地将子实例外键ID添加为序列化器列表字段?

时间:2019-04-22 04:31:33

标签: python django django-rest-framework

我有一个多对多的模型,例如RequestRequestItemItem,并且我希望来自Request API端点的响应包括一个Item个ID的列表。我有一个有效的序列化方法,如下所示:

def to_representation(self, instance: Request) -> typing.Dict[str, Any]:
    representation: Dict = super().to_representation(instance)
    representation["items"] = [
        item_id for item_id
        in instance.requestitems_set.values_list("item_id", flat=True)
    ]
    return representation

如您所见,这太可怕了。获得完全相同的输出的惯用方式是什么?

3 个答案:

答案 0 :(得分:1)

根据给定的信息,您可以减少 for循环 的使用

def to_representation(self, instance: Request) -> typing.Dict[str, Any]:
    representation: Dict = super().to_representation(instance)
    representation["items"] = list(instance.requestitems_set.values_list("item_id", flat=True))
    return representation

答案 1 :(得分:1)

可以像序列化程序中的其他任何字段一样非常简单地添加

class RequestSerializer(serializers.ModelSerializer):
    ....
    items = serializers.SlugRelatedField(
        source='requestitems_set',
        slug_field='item_id',
        read_only=True,
        many=True,
    )

然后将其添加到字段列表中

答案 2 :(得分:0)

DRF实现的related fields很少。但是,API已开放供您实现自己的API。我认为这是更具可读性和简洁的解决方案。

class ItemIdRelatedField(serializers.RelatedField):
    def to_internal_value(self, data):
        pass
        # implement if you need it.

    def to_representation(self, value):
        return value.item_id

像这样在序列化程序中将其用作字段。

items = ItemIdRelatedField(many=True, source='requestitems_set', queryset=RequestItem.objects.all())