Django Rest framework中序列化A表(主表)时怎么获取B表(从表)的数据
有如下模型,作者表Author为主表,图书表Book为从表
from django.db import models # Create your models here. class Author(models.Model): """ 图书作者表 """ name = models.CharField('作者姓名', max_length=20) age = models.SmallIntegerField('年龄') def __str__(self): return self.name class Book(models.Model): """ 图书表 """ book_name = models.CharField('图书名称', max_length=100) author = models.ForeignKey(Author, related_name='author_book') publish_time = models.DateTimeField('出版时间', auto_now_add=True) def __str__(self): return self.book_name
其中图书表的author字段为外键,表示多个图书对应一个作者(现实中其实也可以是一个图书对应多个作者,这就是多对多关系,此处简化为多对一关系)
视图类如下:
from rest_framework import generics, serializers from ..models import Author class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = '__all__' class AuthorList(generics.ListAPIView): """ 查询所有作者信息,及其对应编写的书籍 """ queryset = Author.objects.all() serializer_class = AuthorSerializer
上面只对Author模型进行序列化,则输出接口信息为:
假设,现在有需求为:返回作者对应的所有书籍信息。
分析:
以上序列化实现了只读取Author一个模型的信息,所以接口返回只是自身的表字段,那么需要返回对应书籍信息则需要跨表从book模型取数据。
改造Author的序列化器为如下:
class AuthorSerializer(serializers.ModelSerializer): # 该字段信息通过下方的get_books方法获取数据 books = serializers.SerializerMethodField() class Meta: model = Author fields = '__all__' # 方法名称必须与上面定义的序列化字段一致,格式为:"get_自定义字段名",参数:author_obj为主表author对象,用小写 def get_books(self, author_obj): # 通过book模型中的author字段的related_name反查出作者对应的图书集合 # 如果外键没有指定related_name参数,则使用 author_obj.book_set.all()获取从表的数据。注意这里的book要用小写 book_query_set = author_obj.author_book.all() # 遍历图书集合获取图书的名称和出版时间,并返回 return {'count': book_query_set.count(), "data": [{'name': book_obj.book_name, 'publish_time': book_obj.publish_time} for book_obj in book_query_set]}
此时接口返回信息为:
满足要求,实现