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",
]