Python 如何在Django Rest框架中使用SerializerMethodField以原始形式返回列表外键字段?

Python 如何在Django Rest框架中使用SerializerMethodField以原始形式返回列表外键字段?,python,django,serialization,django-rest-framework,Python,Django,Serialization,Django Rest Framework,型号: 查询集: class Author(models.Model): name = models.CharField() class Book(models.Model): author = models.ForeignKey("Author") title = models.CharField() subtitle = models.CharField() def get_full_title(self): return "{title}: {sub

型号:

查询集:

class Author(models.Model):
  name = models.CharField()

class Book(models.Model):
  author = models.ForeignKey("Author")
  title = models.CharField()
  subtitle = models.CharField()

  def get_full_title(self):
        return "{title}: {subtitle}.".format(title=self.title, subtitle=self.subtitle)
期望响应:

queryset = Author.prefetch_related("book_set").all()
这里的问题是,如果在
Authors.book\u set
列表中使用
serializers.ListSerializer()
,我将在该列表中获得一个完整的模型及其所有字段

如果您尝试使用
序列化程序.SerializerMethodField
,DRF将不允许您在多个结果上使用它。SerializerMethodField不支持多个AKA
序列化程序选项。SerializerMethodField(many=True)
这里我应该注意到,可以编写一个循环遍历结果并将结果累加为字符串的方法,但这限制了您进一步扩展这段代码

p.S.我把这个问题作为参考,因为我在其他地方找不到答案。查看下面的答案以了解更多详细信息


p.p.S.我知道托尔金写了超过4本书。

首先,您需要创建一个自定义列表序列化程序,该序列化程序的方法将返回具有所需表示形式的字符串

[
    {
        "id": 1,
        "name": "J. R. R. Tolkien",
        "books": [
            "The Hobbit: or There and Back Again",
            "The Fellowship of the Ring: being the first part of The Lord of the Rings.",
            "The Two Towers: being the second part of The Lord of the Rings.",
            "The Return of the King: being the third part of The Lord of the Rings."
        ]
    },
    {
        "id": 2,
        "name": "Peter Thiel",
        "books": [
            "The Diversity Myth: Multiculturalism and Political Intolerance on Campus.",
            "Zero to One: Notes on Startups, or How to Build the Future."
        ]
    }
]
其次,您需要用初始模型中不存在的新字段
“books”
装入常规模型序列化程序。然后将新的序列化程序分配给此字段,作为子字段,您可以指定自定义的
SerializerMethodField
调用

class AutorBookSetSerializer(serializers.ListSerializer):

    def get_custom_repr(self, obj):
        return obj.get_full_title()
Q:为什么会有人需要这个

A:如果
“title”
字段更复杂,比如外键,您只想获取值本身,而不获取整个模型,那么可以使用此结构在
get_custom_repr
方法中定义该逻辑

class AuthorSerializer(serializers.ModelSerializer):

    books = AutorBookSetSerializer(child=serializers.SerializerMethodField('get_custom_repr'))

    class Meta:
        model = Author

        fields = [
            "id",
            "name",
            "books",
        ]