0
点赞
收藏
分享

微信扫一扫

drf自定义返回的外键类型:source+序列化器嵌套+model自定义字段

yeamy 2022-02-04 阅读 41

一. 序列化器单独放外键字段,

如果是不经过处理,会返回id: "teacher"返回外键的id值

二. source

a. 适用于查询一个字段的 "teacher_name": "dbj",

b. 查询多个需要进行,写多个(不方便,如果是一层外键的话,我们一般用序列化器嵌套)

teacher_name = serializers.CharField(source='teacher.name')
teacher_id = serializers.CharField(source='teacher.id')

三. 序列化器嵌套,
a. 会把当前对象,需要的属性,以字典的形式返回

b. 序列化器名称必须是关联属性名称(外键名称)

c. 如果是多对一,不需要加任何参数,(课程多,老师一)站在多的一方看

d. 如果是一对多,需要在实例化对象的时候,加一个many=True且必须用related_name对应的值,作为序列化的名称

e. related_name 详细介绍

related_name详细介绍icon-default.png?t=M0H8https://blog.csdn.net/qq_52385631/article/details/122780202?spm=1001.2014.3001.5502

# 序列化器嵌套
class Teacher(serializers.ModelSerializer):
    class Meta:
        model = models.Teacher
        fields = ['id', 'name', 'get_role_display', 'title']


class CourseListModelSerializer(serializers.ModelSerializer):
    """课程列表序列化器"""

    teacher = Teacher()
    # teacher = Teacher(many=True) # 多对一

    class Meta:
        model = models.Course
        fields = ['id', 'name']

四. 如果是多层外键,获取数据

a. A-B-C,我们在A需要C的字段属性,那么一般不要序列化器嵌套,此时一般其所属的model自定义一个函数,

@property
    def get_course_lesson(self):
        # related_name--反向查询的时候使用,代替表名小写_set,直接到了objects这一层,如果A/B都在C处有外键,那么在C处的外键,必须related_name起一个别名
        course_lesson = self.course_lesson.filter(is_show_list=True).values('id', 'name', 'free_trail', 'lesson')
        return course_lesson

b. 在fields字段正常配置即可

class CourseListModelSerializer(serializers.ModelSerializer):
    """课程列表序列化器"""

    # 1.序列化器单独放外键字段,不经过处理,会返回id "teacher": 1,

    class Meta:
        model = models.Course
        fields = ['id', 'name', 'get_course_lesson']


五. 混用

# 知识点1 序列化器嵌套
class Teacher(serializers.ModelSerializer):
    class Meta:
        model = models.Teacher
        fields = ['id', 'name', 'get_role_display', 'title', 'signature']


class CourseListModelSerializer(serializers.ModelSerializer):
    """课程列表序列化器"""

    # 1.序列化器单独放外键字段,不经过处理,会返回id "teacher": 1,

    # 2.source 适用于查询一个字段的  # "teacher_name": "李老师",查询多个需要进行,写多个(不方便,如果是一层外键的话,我们一般用序列化器嵌套)
    # teacher_name = serializers.CharField(source='teacher.name')
    # teacher_id = serializers.CharField(source='teacher.id')
    # 3.序列化器嵌套,会把当前对象,需要的属性,以字典的形式返回
    # a. 序列化器名称必须是关联属性名称(外键名称),b. 如果是多对一,不需要加任何参数,如果是一对多,需要在序列化器加一个many=True且必须用related_name对应的值,作为序列化的名称
    teacher = Teacher()

    # 4. 如果是多层外键,A-B-C,我们在A需要C的字段属性,那么一般不要序列化器嵌套,此时一般其所属的model自定义一个函数,
    class Meta:
        model = models.Course
        fields = ['id', 'name', 'course_img', 'status', 'students', 'lessons', 'pub_lessons', 'price',
                  'attachment_path', 'teacher', 'get_course_lesson']
举报

相关推荐

0 条评论