ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

django-rest-framework学习之路-10-序列化字段

2022-06-03 11:34:09  阅读:161  来源: 互联网

标签:10 null name models rest student 序列化 class


django-rest-framework学习之路-10-序列化字段

1、ModelSerializer类序列化模型

我们一般要序列化模型,可以通过继承ModelSerializer类来实现,这个类与常规的Serializer类一样,不同点在于:

  • 它根据模型自动生成一组字段。
  • 它自动生成序列化器的验证器,比如unique_together验证器。
  • 它默认简单实现了.create()方法和.update()方法。

序列化学生类

我们的模型是这样子的(models.py)

学生表和课程表

from django.db import models


# Create your models here.
class Course(models.Model):
    """
    verbose_name     备注
    max_length  最大长度
    unique  是否唯一
    null    数据库是否可以为null
    blank   前端是否必填
    choices 可选的值 [['数据库可存入的值','前端显示的值'],['数据库可存入的值','前端显示的值']]
    default 默认值
    auto_now_add    第一次保存数据时更新时间
    auto_now    每次保存数据时更新时间

    on_delete 删除该外键时,该条数据的值的处理方式 是设置为NULL 还是也删除该条数据 还是其他...
    """

    # 课程号 最大长度30 唯一 不可为null 前端不可不填
    course_no = models.CharField(verbose_name="课程", max_length=30, unique=True, null=False, blank=False)
    # 课程名称 最大长度30 不可为null 前端不可不填
    course_name = models.CharField(verbose_name="课程名称", max_length=30, null=False, blank=False)
    create_time = models.DateTimeField("创建时间", auto_now_add=True)
    update_time = models.DateTimeField("创建时间", auto_now=True)


class Student(models.Model):
    # 学号 最大长度30 唯一 不可为null 前端不可不填
    student_no = models.CharField(verbose_name="学号", max_length=30, unique=True, null=False, blank=False)
    # 姓名 最大长度30 不可为null 前端不可不填
    student_name = models.CharField(verbose_name="姓名", max_length=30, null=False, blank=False)
    # 性别 男、女、未知 默认未知
    student_sex = models.CharField(verbose_name="性别",
                                   max_length=2,
                                   choices=[[-1, '未知'], [1, '男'], [0, '女'], ],
                                   default=-1)
    # 出生日期 不可为null 前端不可不填
    student_birthday = models.DateField(verbose_name="出生日期", null=False, blank=False)
    # 所选课程 可为null 前端可不填 删除对应课程时,该项数据设置为NULL
    course = models.ForeignKey("Course", verbose_name="所选课程", null=True, blank=True, on_delete=models.SET_NULL)
    create_time = models.DateTimeField("创建时间", auto_now_add=True)
    update_time = models.DateTimeField("创建时间", auto_now=True)

指定序列化字段

设置fields = '__all__'序列化所有字段。

class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = '__all__'  # 序列化所有字段

设置fields = ['student_no', 'student_name', 'student_sex', 'student_birthday', 'course', ]序列化指定字段

class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ['student_no', 'student_name', 'student_sex', 'student_birthday', 'course', ]  # 表示序列化指定字段

设置exclude = ['student_name', 'student_sex', ] 指定排除的字段

class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        exclude = ['student_name', 'student_sex', ]  # 指定排除的字段

遍历嵌套序列化

设置depth = 1表示遍历序列化深度为1,应该设置一个整数n,表示遍历到第n层,不设置遍历只显示外键ID,设置了会显示外键的详细信息

设置后

image-20220529184805567

设置前

image-20220529184932257

设置只读字段

设置read_only_fields = ('student_no', 'student_sex') 表示只读字段

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = '__all__'  # 序列化所有字段
        # fields = ['student_no', 'student_name', 'student_sex', 'student_birthday', 'course', ]  # 表示序列化指定字段
        # exclude = ['student_name', 'student_sex', ]  # 指定排除的字段
        depth = 0
        read_only_fields = ('student_no', 'student_sex')  # 设置只读字段

添加额外的约束

通过extra_kwargs设置一些额外的限制添加,例如默认姓名为无名氏,默认选择男,可选的参数根据字段类型,比如int可以设置min_value和max_value string类型可以设置initial

extra_kwargs = {'student_no': {'initial': '无名氏', },  # 前端界面默认名字为无名氏
                'student_sex': {'initial': 1}  # 前端界面默认是男
                }

界面如下

image-20220530221206628

可以根据这里添加 https://www.w3cschool.cn/lxraw/lxraw-u4kq35ot.html

image-20220603110932678

查看ModelSerializer类

如果想看到序列化出来的序列化类是怎么定义的,可以这样

print(repr(StudentSerializer()))

输出

image-20220603101211278

添加额外的字段

假设要多传入一个参数,key为xixi,只要这样定义即可,因为学生模型中没有xixi,因此我只要该字段是可通过post|put|等传入,也就是只写

class StudentSerializer(serializers.HyperlinkedModelSerializer):
    xixi = serializers.CharField(label="额外字段xx", required=True, write_only=True)

    class Meta:
        model = Student
        fields = ['url', 'id', 'student_no', 'student_name', 'student_sex', 'student_birthday', 'course', "xixi"]
        depth = 0

这个时候,我们就可以传入参数了,然后我们需要对该参数进行处理,处理完,需要pop出该参数,不然直接传给学生模型,创建的时候就会不认识该key

我找到一个地方,可以进行上面的处理,就是StudentViewSet中,重写perform_create方法,程序执行是先调用perform_create方法,然后会进入到StudentSerializer序列化类中的save方法,因此这么处理

def perform_create(self, serializer):
    if serializer.validated_data['xixi'] == "xix":
        print("输入的是xix")
    else:
        print(f"输入的是:{serializer.validated_data['xixi']}")
    serializer.validated_data.pop("xixi")
    return super(StudentViewSet, self).perform_create(serializer)

2、HyperlinkedModelSerializer序列化模型

以超链接的显示序列化模型,而不是通过主键,默认包含url字段

class StudentSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Student
        fields = '__all__'  # 序列化所有字段
        depth = 1

返回的数据格式

image-20220530221853851

当然可以显示的添加ID字段

class StudentSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Student
        fields = ['url', 'id', 'student_no', 'student_name', 'student_sex', 'student_birthday', 'course', ]
        depth = 0

返回的数据格式

image-20220530222204411

标签:10,null,name,models,rest,student,序列化,class
来源: https://www.cnblogs.com/rainbow-tan/p/16339712.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有