Создание объектов внешнего ключа внутри сериализатора
У меня есть две модели:
class Author(models.Model):
name = models.CharField(max_length=255)
class Books(models.Model)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books_author')
name = models.CharField(max_length=255)
Теперь мне нужно создать автора и связанные с ним книги в одном запросе внутри create serializer. Входящие данные будут выглядеть примерно так:
{
"author": "John Doe"
"books":[
{
"name": "Life of Pie"
},
{
"name": "Lord of the rings"
}
]
}
Как я могу сделать это без использования цикла for внутри сериализатора create?
Вложенные сериализаторы доступны только для чтения, вам нужно переопределить метод create
, а самый простой метод - использовать цикл for.
# serializers.py
class BooksSerializer(serializers.ModelSerializer):
class Meta:
model = Books
fields = ('name',)
class AuthorSerializer(serializers.ModelSerializer):
books = BooksSerializer(source='books_author', many=True)
def create(self, validated_data):
books_data = validated_data.pop('books_author')
author = Author.objects.create(**validated_data)
for book in books_data:
Books.objects.create(author=author, **book)
return author
class Meta:
model = Author
fields = ('name', 'books')
Обратите внимание, что я использовал "имя", а не "автор", так как это кажется более логичным, поэтому вам нужно использовать следующее тело:
{
"name": "John Doe",
"books": [
{
"name": "Life of Pie"
},
{
"name": "Lord of the rings"
}
]
}
То же самое относится к методу update
.
Более подробно в официальной документации.
В качестве примечания, я бы:
- переименуйте
Books
вBook
(models.py) - измените
related_name='books_author'
наrelated_name='books'
(models.py) - переименуйте
BooksSerializer
вBookSerializer
(serializers.py) - замените
books = BooksSerializer(source='books_author', many=True)
наbooks = BooksSerializer(many=True)
(serializers.py)
Это сделает ваш код более читабельным.