在Django序列化器中创建外键对象:单请求建作者及关联书籍(无循环)
Django中一次性创建作者及关联书籍(无循环实现)
原模型定义
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)
需求说明
通过单个请求创建作者及其关联的多本书籍,传入数据格式如下:
{ "author": "John Doe", "books":[ { "name": "Life of Pie" }, { "name": "Lord of the rings" } ] }
实现方案
核心思路是利用DRF的ListSerializer结合Django的bulk_create实现批量创建,避免手动编写循环:
1. 定义书籍序列化器及批量处理序列化器
from rest_framework import serializers class BookSerializer(serializers.ModelSerializer): class Meta: model = Books fields = ['name'] class BookListSerializer(serializers.ListSerializer): def create(self, validated_data): # 使用bulk_create批量插入,无需手动循环 return Books.objects.bulk_create([Books(**item) for item in validated_data])
2. 关联书籍序列化器与批量序列化器
修改BookSerializer的元类,指定使用自定义的批量序列化器:
class BookSerializer(serializers.ModelSerializer): class Meta: model = Books fields = ['name'] list_serializer_class = BookListSerializer
3. 编写主序列化器处理完整请求
class AuthorWithBooksSerializer(serializers.Serializer): author = serializers.CharField(max_length=255) books = BookSerializer(many=True) def create(self, validated_data): # 先创建作者实例 author = Author.objects.create(name=validated_data['author']) # 给所有书籍数据补充author外键关联 book_data = [ {**book_item, 'author': author} for book_item in validated_data['books'] ] # 调用书籍批量序列化器的create方法完成批量创建 self.fields['books'].create(book_data) return author
关键说明
bulk_create通过单条SQL语句完成批量插入,比循环调用create性能更高ListSerializer封装了批量处理逻辑,避免在主序列化器的create方法中编写循环- 只需给书籍数据补充关联的作者实例,剩下的批量创建逻辑由序列化器自动处理
内容的提问来源于stack exchange,提问作者Arthur Dayne
相关产品推荐
相关产品推荐

