Models:
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:
queryset = Author.prefetch_related("book_set").all()
Desired Responce:
[
{
"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."
]
}
]
The problem here is that if you use serializers.ListSerializer()
on Authors.book_set
list, I will get an entire model in that list with all it's fields.
If you try to use serializers.SerializerMethodField
, DRF would not let you use it on multiple results. SerializerMethodField doesn't support an option many AKA serializers.SerializerMethodField(many=True)
I should note here that one could write a method that cycles through the results and accumulates them into a string, but that limits you from further extending this piece of code.
PS I'm posting this question as a reference, since I couldn't find an answer anywhere else. Check the answer below for more details.
PPS I know that Tolkien wrote more than 4 books.
First, you need to create a custom list serializer with a method that will return a string with needed representation.
class AutorBookSetSerializer(serializers.ListSerializer):
def get_custom_repr(self, obj):
return obj.get_full_title()
Second, you need to crate your regular model serializer with a new field "books"
that is not present in your initial model. Then you assign your new serializer to this field and as a child you can specify your custom SerializerMethodField
call.
class AuthorSerializer(serializers.ModelSerializer):
books = AutorBookSetSerializer(child=serializers.SerializerMethodField('get_custom_repr'))
class Meta:
model = Author
fields = [
"id",
"name",
"books",
]
Q: Why would anyone possibly ever need this?
A: If "title"
field was something more complex, like a foreign key, where you would only want to get the value itself and not fetch the entire model, you could use this structure to define that logic inside of get_custom_repr
method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.