首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DRF ListSerializer和ListField

DRF ListSerializer和ListField
EN

Stack Overflow用户
提问于 2018-07-24 03:16:39
回答 2查看 10.9K关注 0票数 2

我在我的项目中使用django rest,直到现在我使用了ListSerializer的对象列表,当我需要搜索并到达ListField的列表的最小长度和最大长度时。

在此之前,我的代码被罚款,没有任何错误和不当行为。现在我使用ListField作为列表字段序列化程序,但是我没有得到什么时候使用ListSerializer?有人能解释一下ListSerializer和FieldSerializer之间的区别吗?

我用ListSerializer编写的示例代码:

代码语言:javascript
复制
tags = serializers.ListSerializer(child=serializers.CharField(allow_blank=False), required=False)

我用ListField编写的示例代码:

代码语言:javascript
复制
open_hour = serializers.ListField(child=serializers.DictField(), max_length=7, min_length=7)
EN

回答 2

Stack Overflow用户

发布于 2018-07-24 09:13:19

免责声明:此答案不完整

有人能解释一下ListSerializer和FieldSerializer之间的区别吗?

我想问题是 serializers.ListSerializer serializers.ListField之间的区别

假设我们有两个models作为

代码语言:javascript
复制
class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'


class Album(models.Model):
    artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

    def __str__(self):
        return f'{self.name} : {self.artist}'

serializer作为

代码语言:javascript
复制
class AlbumSerializer(serializers.ModelSerializer):
    artist = serializers.StringRelatedField()

    class Meta:
        fields = '__all__'
        model = Album


class MusicianSerializer(serializers.ModelSerializer):
    AlbumSerializer(many=True, source='album_set')

    class Meta:
        fields = '__all__'
        model = Musician

ListSerializer

如官方DRF文档中所述

在实例化序列化程序并传递many=True时,将创建一个ListSerializer实例。序列化程序类随后成为父child的ListSerializer。

例如,我们可以将MusicianSerializer重写为ListSerializer

代码语言:javascript
复制
class MusicianSerializer(serializers.ModelSerializer):
    albums = serializers.ListSerializer(child=AlbumSerializer(), source='album_set')

    class Meta:
        fields = '__all__'
        model = Musician

它会产生和以前一样的结果。但是,如果我们试图使用ListField而不是ListSerializer,它将引发一个错误

代码语言:javascript
复制
'RelatedManager' object is not iterable

当我检查源代码时,我发现ListSerializerListField都是从同一个类继承的(父类和父类是相同的)。

票数 7
EN

Stack Overflow用户

发布于 2022-10-19 02:51:48

我遇到了同样的问题,我相信我找到了解决办法!

诀窍是您需要创建一个新的序列化程序,该序列化程序继承ListSerializer类并覆盖to_representation()方法以输出所需的格式。

如果您查看ListSerializer的DRF源代码,可以看到默认的to_representation()方法如下.

代码语言:javascript
复制
def to_representation(self, data):
        """
        List of object instances -> List of dicts of primitive datatypes.
        """
        # Dealing with nested relationships, data can be a Manager,
        # so, first get a queryset from the Manager if needed
        iterable = data.all() if isinstance(data, models.Manager) else data

        return [
            self.child.to_representation(item) for item in iterable
        ]

示例

模型

代码语言:javascript
复制
class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'


class Album(models.Model):
    artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

    def __str__(self):
        return f'{self.name} : {self.artist}'

串行化

代码语言:javascript
复制
class AlbumSerializer(serializers.ModelSerializer):
    artist = serializers.StringRelatedField()

    class Meta:
        fields = '__all__'
        model = Album

class AlbumKeyValueSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        reaction_count_set = {}
        for item in data.all():
            reaction_count_set[item.name] = item.artist

        return reaction_count_set

class MusicianSerializer(serializers.ModelSerializer):
    AlbumKeyValueSerializer(child=AlbumSerializer(), source='album_set')

    class Meta:
        fields = '__all__'
        model = Musician
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51489952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档