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]}

 

此时接口返回信息为:

 

满足要求,实现 

 

posted @ 2019-12-26 13:39  秋寻草  阅读(1372)  评论(0编辑  收藏  举报