【无标题】

关联序列化器序列化

默认外键序列化

之前的序列化,只是简单的对一张表进行处理,那么如果遇到一对一多对一多对多的情况该咋序列化呢,我们来看看

比如现在有两张很常见的关联表老师表学生表

  • 一个老师可以有一群学生,但是一个学生只能有一个老师

 class Teacher(models.Model):
     name = models.CharField(max_length=30, verbose_name='老师名')
     age = models.IntegerField(verbose_name='年纪')
     
     def __str__(self):
         return self.name
     
 ​
 class Student(models.Model):
     name = models.CharField(max_length=30, verbose_name='学生名')
     teacher = models.ForeignKey(
         Teacher, on_delete=models.SET_NULL, 
         null=True, blank=True, 
         verbose_name='关联老师'
     )
     def __str__(self):
         return self.name

学生表中,包含外键teacher,外键可以通过如下一些方式进行序列化

 StringRelated外键序列化

关联表__str__方法作为结果返回,设置read_only代表该字段不进行反序列化校验

 class StudentSer(serializers.ModelSerializer):
     teacher = serializers.StringRelatedField()
     class Meta:
         model = Student
         fields = '__all__'

编写返回一个学生的接口

 class StudentDetail(APIView):
     def get(self, request):
         id_ = request.query_params.get('id')
         # 通过 GET 传参获取当前学生 ID
         try:
             stu = Student.objects.get(pk=id_)
         except Student.DoesNotExist:
             return Response({'error': '查不到结果'})
         ser = StudentSer(instance=stu)
         return Response(ser.data, status=200)

接口返回效果如下

 {
     "id": 1,
     "teacher": "张老师", # teacher 表的__str__方法所返回的
     "name": "小红"
 }

SlugRelated外键序列化

使用关联表的指定字段作为结果返回

 class StudentSer(serializers.ModelSerializer):
     teacher = serializers.SlugRelatedField(read_only=True, slug_field='name')
     class Meta:
         model = Student
         fields = '__all__'

效果就很直观了,返回的就是slug_field字段所对应的模型层里这个字段代表的值

 {
     "id": 1,
     "teacher": 20,
     "name": "小红"
 }

 PrimaryKeyRelated外键序列化

关联表主键作为结果返回,使用PrimaryKeyRelatedField字段,该字段需要包含querysetread_only属性

 class StudentSer(serializers.ModelSerializer):
     teacher = serializers.PrimaryKeyRelatedField(read_only=True)
     class Meta:
         model = Student
         fields = '__all__'

返回的数据类似如下效果

 {
     "id": 1,
     "teacher": 1,
     "name": "小红"
 }

外键自定义序列化方式

自己构建序列化字段, 此时默认的外键不发生改变,新添加序列化字段

 class StudentSer(serializers.ModelSerializer):
     teacher_name = SerializerMethodField(read_only=True)
 ​
     # 为了获取自定义字段,需要实现一个方法, 方法名: get_字段名
     def get_teacher_name(self, obj):
         # obj 代表当前需要序列化的对象, 此时obj就是学生对象
         return obj.teacher.name
     
     class Meta:
         model = Student
         fields = '__all__'

返回的数据类似如下效果

 {
     "id": 1,
     "teacher": 1,
     "teacher_name": '李老师',
     "name": "小红"
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值