zoukankan      html  css  js  c++  java
  • Django(46)drf序列化类的使用(ModelSerializer)

    前言

    我们上篇文章使用到了Serializer类,可能有小伙伴说太过复杂,那么本篇就为大家带来更加简便的序列化类ModelSerializer
     

    ModelSerializer

    先来看下ModelSerializer的代码结构如下:

    可以看到ModelSerializer是继承自Serializer,官方是这么介绍到的

    ModelSerializer只是一个常规的Serializer,只是做了以下事情

    • 将自动填充一组默认字段
    • 将自动填充一组默认验证程序
    • 提供了默认的.create().update()实现

    我们将之前的Serializer类现在用ModelSerializer来实现

    class StudentModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = Student
            fields =  ['id', 'name', 'age', 'sex']
    

    默认情况下,所有的模型的字段都将映射到序列化器上相应的字段。
    如果你希望在模型序列化器中使用默认字段的一部分,你可以使用fieldsexclude选项来执行此操作

    • fields:需要哪些模型字段
    • exclude:排除哪些模型字段

    官方强烈建议你使用fields属性显式的设置要序列化的字段。这样就不太可能因为你修改了模型而无意中暴露了数据。
    如果我们需要使用模型的全部字段,则可以将fields属性设置成'__all__'

    默认情况下,fields里的字段既参加序列化也参加反序列化,如果我们想某个字段只序列化或反序列化可以定义extra_kwargs字段,代码如下:

    class StudentModelSerializer(serializers.ModelSerializer):
        # classes = ClassesModelSerializer(read_only=True)
        class Meta:
            model = Student
            fields =  ['id', 'name', 'age', 'sex', 'password']
            extra_kwargs = {
                "password": {
                    "write_only": True
                },
               "id": {
                   "read_only": False
               }
            }
    

    上面代码如果不写extra_kwargs,那么password默认参加序列化和反序列化,那么密码就会返回给前端了,这里我们定义了extra_kwargs字段,在字段中设置了password只能反序列化,那么用户只能提交密码,而后台不会返回密码给前台
    当然,extra_kwargs也可以自定义错误信息,如果业务有需要,可以查看官方文档
     

    指定嵌套序列化

    上面我们都是单模型的序列化,但是实际业务中我们不会这么简单,一定会遇到关系模型的序列化,下面我们来讲解关系模型的序列化
    首先我们看一下models模型内容:

    class Classes(models.Model):
        name = models.CharField(max_length=20, verbose_name="班级名")
    
        class Meta:
            db_table = "classes"
    
    
    class Student(models.Model):
    
        SEX_CHOICES = (
            (1,'男'),
            (2, '女')
        )
    
        name = models.CharField(max_length=20, verbose_name='姓名')
        age = models.IntegerField(null=True, blank=True, verbose_name='年龄')
        sex = models.IntegerField(choices=SEX_CHOICES, default=1, verbose_name='性别')
        classes = models.ForeignKey(Classes, on_delete=models.SET_NULL, verbose_name="班级", null=True, related_name='students')
        class Meta:
            db_table = "student"
    

    我们定义了Student学生类,里面定义了一个外键classes关联Classes,一个班级中可以有多个学生,而一个学生只能属于一个班级,典型的一对多的关系,接下来我们看序列化函数

    class ClassesModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = Classes
            fields = ['id', 'name', 'students']
    
    
    class StudentModelSerializer(serializers.ModelSerializer):
        classes = ClassesModelSerializer(read_only=True)
        class Meta:
            model = Student
            fields =  ['id', 'name', 'age', 'sex', 'classes']
    

    我们在StudentModelSerializer中增加了一个额外的字段classes,并将字段设置为只读,一般外键只做序列化,并且在fields列表中添加了该字段。
    注意:我们在创建外键模型时,必须在外键中设置related_name,如果没设置,序列化时不会返回关联的外键内容

    接下来我们访问http://127.0.0.1:8000/drf/student/,会看到返回的学生表中包含了班级表的内容,如下

    {
        "id": 1,
        "name": "jkc",
        "age": 18,
        "sex": 1,
        "classes": {
            "id": 1,
            "name": "班级1",
            "students": [
                1,
                15,
                18
            ]
        }
    },
    
  • 相关阅读:
    Spring的历史和哲学
    CORS简介
    LDAP概念了解
    Restful levels&HATEOAS
    python/mysql connector
    Session&Cookie 简介及使用
    XML简介
    Json简介
    《魅族官网》
    期末设计部分代码截图
  • 原文地址:https://www.cnblogs.com/jiakecong/p/14854690.html
Copyright © 2011-2022 走看看