Django-drf架构 序列化的详解

Django-drf架构 序列化的详解

一、为什么使用序列化器?

序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型,然后可以将它们轻松地呈现为 JSONXML 或其他内容类型。

序列化器还提供反序列化,在首次验证传入数据之后,可以将解析的数据转换回复杂类型。

二、创建模型类:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
# Create your models here.
from django.db import models


class Course(models.Model):
    """课程表"""
    name = models.CharField(verbose_name='课程名称', max_length=255)
    description = models.TextField(verbose_name='课程描述信息', null=True)
    price = models.DecimalField(verbose_name=u'课程价格', max_digits=15, decimal_places=2, default=0.0)
    deleted = models.BooleanField(verbose_name='课程是否被删除', default=False)
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    edited_at = models.DateTimeField(auto_now=True)


class User(models.Model):
    """用户表:记录用户常用信息"""
    name = models.CharField(verbose_name=u'用户的姓名', max_length=32, null=True)
    mobile = models.CharField(verbose_name=u'用户的手机号', max_length=32, unique=True)
    courses = models.ManyToManyField(verbose_name=u'关联课程', to='Course', through='UserCourse', related_name='user_course')


class UserExtra(models.Model):
    """用户信息额外表: 存储一些用户不常用信息"""
    birthday = models.CharField(verbose_name=u'生日', max_length=32, null=True)
    email = models.EmailField(verbose_name=u'邮箱', null=True)
    user = models.OneToOneField(to=User, related_name='extra')  # 跟User表是一对一的关系


class UserCourse(models.Model):
    """课程表跟用户表手动添加的多对多表"""
    course = models.ForeignKey('Course', related_name='my_course')
    user = models.ForeignKey('User', related_name='my_user')


class Coursechapter(models.Model):
    """课程章节表"""
	MAIN_COURSE = 0  # 专业课
    PUBLIC_COURSE = 1  # 公共课
    MANAGEMENT_COURSE = 2  # 管理类联考: MBA等管理类专业硕士
    CERTIFICATES_COURSE = 3  # 资格证书:MATCFE等

    category_choices = (
        (MAIN_COURSE, u'专业课'),
        (PUBLIC_COURSE, u'公共课'),
        (MANAGEMENT_COURSE, u'管理课'),
        (CERTIFICATES_COURSE, u'资格证书')
    )

    category = models.SmallIntegerField(verbose_name=u'章节分类', 
                                        choices=category_choices, default=MAIN_COURSE,
                                        db_index=True)
    name = models.CharField(verbose_name='课程名称', max_length=255)
    description = models.TextField(verbose_name='课程描述信息', null=True)
    course = models.ForeignKey('Course', related_name='course_chapter', null=True)
  • 执行以下命令进行数据库的迁移:

    python manage.py makemigrations app_name[应用的名称]
    python manage.py migrate app_name[应用的名称]
    

三、Django的序列化方法:

  • 首先举个手动序列化的方法

    import json
    
    from django.shortcuts import HttpResponse
    
    
    class UserView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 返回的是query_set, 里面包含的是字典
            user_list = models.User.objects.values('id', 'name', 'mobile')
    
            # 转换成列表
            user_list = list(user_list)
    	    # 转换成Json数据格式
            user_json = json.dumps(user_list, ensure_ascii=False)
    	    # 进行返回
            return HttpResponse(user_json)
    
    # 输出结果:
    [
        {
            "mobile":"13212332322",
            "id":1,
            "name":"东北大学"
        },
        {
            "mobile":"13222233331",
            "id":2,
            "name":"小牛"
        },
        {
            "mobile":"13232132132",
            "id":3,
            "name":"大牛"
        }
    ]
    
  • 使用Django内置的serializers模块

    from django.core import serializers
    from django.shortcuts import HttpResponse
    
    class UserView(View):
    
        def get(self, request, *args, **kwargs):
            
            # 获取User表所有的数据, 返回一个query_set
            user_list = models.User.objects.all()
            
            # 使用django内置的serialize模块, 第一个参数, 执行数据格式, 第二个参数要序列化的数据对象
            ser = serializers.serialize('json', user_list)
            # 进行数据的返回
            return HttpResponse(ser)
    
    # 输出结果如下:
    [
        {
            "model":"apps.user",
            "pk":1,
            "fields":{
                "name":"东北大学",
                "mobile":"13212332322",
                "courses":[
                    2
                ]
            }
        },
        {
            "model":"apps.user",
            "pk":2,
            "fields":{
                "name":"小牛",
                "mobile":"13222233331",
                "courses":[
    
                ]
            }
        },
        {
            "model":"apps.user",
            "pk":3,
            "fields":{
                "name":"大牛",
                "mobile":"13232132132",
                "courses":[
    
                ]
            }
        }
    ]
    

    Django支持三种序列化格式:xml、json、yaml

四、DRF的序列化基本使用:

4.1:继承Serializer类:

  • 基本使用

    from rest_framework import serializers  # 导入模块, 来使用DRF序列化
    
    class UserSerializers(serializers.Serializer):
        """创建一个序列化的类, 继承Serializer类:
            获取User表里字段, id、name、mobile
        """
        id = serializers.IntegerField()
        name = serializers.CharField()
        mobile = serializers.CharField()
    
    
    class UserView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 获取User表所有的数据, 返回一个query_set
            user_list = models.User.objects.all()
    
            # 序列化,两个参数, instance:接收QuerySet或对象
            # many=True 表示对QuerySet进行处理, many=False:表示对 对象进行处理
            ser = UserSerializers(instance=user_list, many=True)
    
            # 转换成json格式, ensure_ascii=False 表示显示中文, 默认为True
            ret = json.dumps(ser.data, ensure_ascii=False)
            # 进行数据的返回
            return HttpResponse(ret)
    
    # 输出结果:
    [
        {
            "id":1,
            "name":"东北大学",
            "mobile":"13212332322"
        },
        {
            "id":2,
            "name":"小牛",
            "mobile":"13222233331"
        },
        {
            "id":3,
            "name":"大牛",
            "mobile":"13232132132"
        }
    ]
    
    from rest_framework import serializers
    
    
    class UserSerializers(serializers.Serializer):
        """创建一个序列化的类, 继承Serializer类:
            获取User表里字段, id、name、mobile
        """
        id = serializers.IntegerField()
        name = serializers.CharField()
        mobile = serializers.CharField()
    
    
    class UserView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 获取User对象
            try:
                user_obj = models.User.objects.get(pk=1)
            except models.User.DoesNotExist:
                return HttpResponse("用户不存在")
    
            # 序列化,两个参数, instance:接收QuerySet或对象
            # many=True 表示对QuerySet进行处理, many=False:表示对 对象进行处理
            ser = UserSerializers(instance=user_obj, many=False)
    
            # 转换成json格式, ensure_ascii=False 表示显示中文, 默认为True
            ret = json.dumps(ser.data, ensure_ascii=False)
            # 进行数据的返回
            return HttpResponse(ret)
    
    # 输出结果:
    {
        "id":1,
        "name":"东北大学",
        "mobile":"13212332322"
    }
    
  • 外键关系使用source、source='get_xxx_display'的序列化:

    import json
    from rest_framework import serializers
    from django.shortcuts import HttpResponse
    
    
    class CourseChapterSerializers(serializers.Serializer):
        """课程章节的序列化:
            获取:id、name、course_name(外键去course表取name字段)、category(章节类型)
        """
        # 获取本表的ID
        id = serializers.IntegerField()
        # 获取本表的name
        name = serializers.CharField()
        # 外键关系:去course表获取name字段
        course_name = serializers.CharField(source='course.name')
        # 定义choices 字段, 可以直接获取详情信息
        category = serializers.ChoiceField(choices=models.Coursechapter.category_choices,
                                           source='get_category_display')
    
    
    class ChapterView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 获取所有章节的信息
            course_chapter_list = models.Coursechapter.objects.all()
    
            # 序列化所有章节信息
            ser = CourseChapterSerializers(instance=course_chapter_list, many=True)
    
            # 转换成json格式, ensure_ascii=False 表示显示中文, 默认为True
            ret = json.dumps(ser.data, ensure_ascii=False)
            # 进行数据的返回
            return HttpResponse(ret)
    
    # 输出结果如下:
    [
        {
            "id":1, // 课程章节的ID
            "name":"第一章",  // 章节的名称
            "course_name":"上海财经大学",  // 章节所对象的课程名称
            "category":"专业课"  // 章节的类型
        },
        {
            "id":2,
            "name":"第二章",
            "course_name":"上海财经大学",
            "category":"专业课"
        }
    ]
    
  • 表示自定义显示(通常ManyToMany),使用SerializerMethodField()

    import json
    from rest_framework import serializers
    from django.shortcuts import HttpResponse
    
    
    class UserSerializers(serializers.Serializer):
        """创建一个序列化的类, 继承Serializer类:
            获取User表里字段, id、name、mobile、courses获取多对多的字段
        """
        id = serializers.IntegerField()
        name = serializers.CharField()
        mobile = serializers.CharField()
    
        # 表示自定义显示, 通常ManyToMany字段时使用
    	# 注意:courses 必须跟 get_courses 是同名的
        courses = serializers.SerializerMethodField()
    
        # row:表示User数据的行
        def get_courses(self, row):
            """自定义写一个方法, 获取User表跟Course表信息"""
            
            # 获取所有User表所对应的Course表数据
            courses_list = row.courses.all()
            my_list = []
    	    # 获取课程ID、课程名称
            for course_obj in courses_list:
                my_list.append({'id': course_obj.id, 'course_name': course_obj.name})
    
            return my_list
    
    
    class UserView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 获取所有用户的信息
            user_list = models.User.objects.all()
    
            # 序列化所有章节信息
            ser = UserSerializers(instance=user_list, many=True)
    
            # 转换成json格式, ensure_ascii=False 表示显示中文, 默认为True
            ret = json.dumps(ser.data, ensure_ascii=False)
            # 进行数据的返回
            return HttpResponse(ret)
    
    # 输出结果:
    [
        {
            "id":1, // User表ID
            "name":"东北大学",  // User表姓名
            "mobile":"13212332322", // User表手机号
            "courses":[  // 用户1 所对应的课程信息
                {
                    "course_name":"上海财经大学",  // 课程名称
                    "id":2  // 课程ID
                }
            ]
        },
        {
            "id":2,
            "name":"小牛",
            "mobile":"13222233331",
            "courses":[
    
            ]
        },
        {
            "id":3,
            "name":"大牛",
            "mobile":"13232132132",
            "courses":[
    
            ]
        }
    ]
    

4.2:继承ModelSerializer类:

ModelSerializer 类提供了一个快捷方式,可让你自动创建一个 Serializer 类,其中的字段与模型类字段对应。

ModelSerializer 类与常规 Serializer 类相同,不同之处在于:

  • 它会根据模型自动生成一组字段。
  • 它会自动为序列化类生成验证器,例如 unique_together 验证器。
  • 它包含 .create().update() 的简单默认实现。
  • 基本使用:

    import json
    from rest_framework import serializers
    from django.shortcuts import HttpResponse
    
    
    class UserSerializers(serializers.ModelSerializer):
        """创建一个序列化的类, 继承ModelSerializer
        """
        class Meta:
            model = models.User
            fields = '__all__'  # '__all__' 代表检索出User表所有的字段 
            # fields = ('name', 'mobile')   代表检索出指定的字段('name', 'mobile')
    
    
    class UserView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 获取所有用户的信息
            user_list = models.User.objects.all()
    
            # 序列化所有章节信息
            ser = UserSerializers(instance=user_list, many=True)
    
            # 转换成json格式, ensure_ascii=False 表示显示中文, 默认为True
            ret = json.dumps(ser.data, ensure_ascii=False)
            # 进行数据的返回
            return HttpResponse(ret)
    
    # 输出结果:
    [
        {
            "id":1, // User的ID
            "name":"东北大学",  // 用户的姓名
            "mobile":"13212332322",  // 用户的手机号
            "courses":[
                2
            ]
        },
        {
            "id":2,
            "name":"小牛",
            "mobile":"13222233331",
            "courses":[
    
            ]
        },
        {
            "id":3,
            "name":"大牛",
            "mobile":"13232132132",
            "courses":[
    
            ]
        }
    ]
    

    以上可以看出,courses的字段,只能显示到course表中的ID,如果想获取它课程名称可以尝试下面这种方法。

  • 指定要包含的字段:

    • 强烈建议你显式使用 fields 属性序列化的所有字段。

      class UserSerializers(serializers.ModelSerializer):
          """创建一个序列化的类, 继承ModelSerializer
          """
          class Meta:
              model = models.User
              fields = ('name', 'mobile')
      
    • 将 fields 属性设置为特殊值 '__all__',以指示应该使用模型中的所有字段

      class UserSerializers(serializers.ModelSerializer):
          """创建一个序列化的类, 继承ModelSerializer
          """
          class Meta:
              model = models.User
              fields = '__all__'  # '__all__' 代表检索出User表所有的字段 
      
    • 将 exclude 属性设置为从序列化程序中排除的字段列表

      class UserSerializers(serializers.ModelSerializer):
          """创建一个序列化的类, 继承ModelSerializer
          """
          class Meta:
              model = models.User
              exclude ='mobile')
      
    • 总结:

      fieldsexclude 属性中的名称通常映射到模型类的模型字段。

      或者fields选项中的名称可以映射成属性或方法。而不会变成模型类中的参数。

      从版本 3.3.0 开始,必须提供其中一个属性 fieldsexclude

4.3:自动序列化连表:

默认的 ModelSerializer 使用主键进行关联,但你也可以使用 depth 选项轻松生成嵌套表示(自关联):

depth 选项应设置为一个整数值,该值指示在还原为平面表示之前应该遍历的关联的深度。

  • 使用depth

    import json
    from rest_framework import serializers
    from django.shortcuts import HttpResponse
    
    
    class UserSerializers(serializers.ModelSerializer):
        """创建一个序列化的类, 继承ModelSerializer
        """
        class Meta:
            model = models.User
            fields = '__all__'  # '__all__' 代表检索出User表所有的字段
            # fields = ('name', 'mobile')   代表检索出指定的字段('name', 'mobile')
            # 表示联表的深度, 连表到Course中, 进行检索出Course表所有的属性
            depth = 1
            
    
    class UserView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 获取所有用户的信息
            user_list = models.User.objects.all()
    
            # 序列化所有章节信息
            ser = UserSerializers(instance=user_list, many=True)
    
            # 转换成json格式, ensure_ascii=False 表示显示中文, 默认为True
            ret = json.dumps(ser.data, ensure_ascii=False)
            # 进行数据的返回
            return HttpResponse(ret)
    
    # 输出结果:
    [
        {
            "id":1, // 用户ID
            "name":"东北大学", // 用户的姓名
            "mobile":"13212332322",  // 用户的手机号
            "courses":[  // 用户所对象的课程信息 (这里使用了depth)
                {
                    "id":2,  // 课程的ID
                    "name":"上海财经大学",  // 课程的名称
                    "description":"课程真的很棒", // 课程的描述
                    "price":"18888.00",  // 课程的价格
                    "deleted":false,  // 课程是否被删除
                    "created_at":"2019-04-29T03:36:53+08:00",  // 课程的创建时间
                    "edited_at":"2019-04-29T03:36:55+08:00"  // 课程的修改时间
                }
            ]
        },
        {
            "id":2,
            "name":"小牛",
            "mobile":"13222233331",
            "courses":[
    
            ]
        },
        {
            "id":3,
            "name":"大牛",
            "mobile":"13232132132",
            "courses":[
    
            ]
        }
    ]
    

    一般不推荐使用depth,因为这样深度的连表可能会获取到前端不需要的数据,那样的话对SQL查询或接口响应有些较慢。

4.4:处理嵌套对象:

前面的例子适用于处理只具有简单数据类型的对象,但有时还需要能够表示更复杂的对象,其中对象的某些属性可能不是简单的数据类型,如字符串,日期或整数。

  • Serializer 类本身就是一种 Field,可以用来表示一个对象类型嵌套在另一个对象类型中的关系。

    import json
    from rest_framework import serializers
    from django.shortcuts import HttpResponse
    
    
    class CourseSerializers(serializers.ModelSerializer):
        """课程的序列化:继承ModelSerializer类"""
        
        # 获取Course表所有的信息
        class Meta:
            model = models.Course
            fields = '__all__'
    
    
    class CourseChapterSerializers(serializers.Serializer):
        """课程章节的序列化:
            获取:id、name、course_name(外键去course表取name字段)、category(章节类型)
        """
        # 获取本表的ID
        id = serializers.IntegerField()
        # 获取本表的name
        name = serializers.CharField()
        # 外键关系:去course表获取name字段
        course_name = serializers.CharField(source='course.name')
        # 定义choices 字段, 可以直接获取详情信息
        category = serializers.ChoiceField(choices=models.Coursechapter.category_choices,
                                           source='get_category_display')
        
        # 处理嵌套对象的序列化
        course = CourseSerializers()
    
    
    class ChapterView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 获取所有课程章节的信息
            chapter_list = models.Coursechapter.objects.all()
    
            # 序列化所有章节信息
            ser = CourseChapterSerializers(instance=chapter_list, many=True)
    
            # 转换成json格式, ensure_ascii=False 表示显示中文, 默认为True
            ret = json.dumps(ser.data, ensure_ascii=False)
            # 进行数据的返回
            return HttpResponse(ret)
    
    # 输出结果:
    [
        {
            "id":1,  // 章节ID
            "name":"第一章",  //章节名称
            "course_name":"上海财经大学",  //课程名称
            "category":"专业课", // 章节类型
            "course":{  // 章节对应的课程信息(嵌套处理)
                "id":1,  // 课程ID
                "name":"上海财经大学",  //课程名称
                "description":"课程很棒", // 课程描述
                "price":"1999.00", // 课程价格
                "deleted":false,  // 课程是否被删除
                "created_at":"2019-04-29T03:36:22+08:00",  // 课程创建时间
                "edited_at":"2019-04-29T03:36:24+08:00"  // 课程修改时间
            }
        },
        {
            "id":2,
            "name":"第二章",
            "course_name":"上海财经大学",
            "category":"专业课",
            "course":{
                "id":1,
                "name":"上海财经大学",
                "description":"课程很棒",
                "price":"1999.00",
                "deleted":false,
                "created_at":"2019-04-29T03:36:22+08:00",
                "edited_at":"2019-04-29T03:36:24+08:00"
            }
        }
    ]
    

    如果嵌套对象可以是 None 值,则应将 required = False 标志传递给嵌套的序列化类。

    class CourseChapterSerializers(serializers.Serializer):
        """课程章节的序列化"""
     	........省略..........
    	 # 处理嵌套对象的序列化
        course = CourseSerializers(required=False)
    

    如果嵌套对象是一个列表,则应将 many = True 标志传递给嵌套的序列化类。

    class CourseChapterSerializers(serializers.Serializer):
        """课程章节的序列化"""
     	........省略..........
    	 # 处理嵌套对象的序列化
        course = CourseSerializers(many=True)
    

4.5:处理多个对象:

  • 要序列化查询集或对象列表而不是单个对象实例,在实例化序列化类时,应该传递 many=True 标志。然后,您可以传递要序列化的查询集或对象列表。

    class ChapterView(View):
    
        def get(self, request, *args, **kwargs):
    
            # 获取所有课程章节的信息
            chapter_list = models.Coursechapter.objects.all()
    
            # 序列化所有章节信息  
            ser = CourseChapterSerializers(instance=chapter_list, many=True)
    
            # 转换成json格式, ensure_ascii=False 表示显示中文, 默认为True
            ret = json.dumps(ser.data, ensure_ascii=False)
            # 进行数据的返回
            return HttpResponse(ret)
    

4.6:包含额外的上下文:

  • 除了被序列化的对象外,还有一些情况需要为序列化类提供额外的上下文。一种常见的情况是,如果你使用的是包含超链接关系的序列化类,则需要序列化类访问当前请求,以便它可以正确生成完全限定的URL。

    serializer = AccountSerializer(account, context={'request': request})
    serializer.data
    # {'id': 6, 'owner': u'denvercoder9', 'created': datetime.datetime(2019, 2, 12, 09, 44, 56, 678870), 'details': 'http://example.com/accounts/6/details'}
    

    通过访问 self.context 属性,可以在任何序列化对象字段逻辑中使用上下文字典。

五、Serializer字段详解:

5.1:Boolean字段:

BooleanField:

表示一个 boolean 值。

使用 HTML 编码表单时需要注意,省略一个 boolean 值被视为将字段设置为 False,即使它指定了 default=True选项。这是因为 HTML 复选框通过省略该值来表示未选中的状态,所以 REST framework 将省略看作是空的复选框。

请注意,将使用 required=False 选项生成默认的 BooleanField 实例(因为 Django models.BooleanField 始终为 blank=True)。如果想要更改此行为,请在序列化类上显式声明 BooleanField

对应与 django.db.models.fields.BooleanField.

签名: BooleanField()

NullBooleanFied:

表示一个布尔值,它也接受 None 作为有效值。

对应与 django.db.models.fields.NullBooleanField.

签名: NullBooleanField()

5.2:字符串字段:

CharField:

表示文本。可以使用 max_lengthmin_length 验证(或限定)文本的长短。

对应与 django.db.models.fields.CharFielddjango.db.models.fields.TextField.

签名: CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)

  • max_length - 验证输入所包含的字符数不超过这个数目。
  • min_length - 验证输入所包含的字符数不少于这个数目。
  • allow_blank - 如果设置为 True,则空字符串应被视为有效值。如果设置为 False,那么空字符串被认为是无效的并会引发验证错误。默认为 False
  • trim_whitespace - 如果设置为 True,则前后空白将被删除。默认为 True

allow_null 选项也可用于字符串字段,尽管它相对于 allow_blank 来说不被推荐。同时设置 allow_blank=Trueallow_null=True 是有效的,但这样做意味着字符串表示允许有两种不同类型的空值,这可能导致数据不一致和微妙的应用程序错误。

EmailField:

表示文本,将文本验证为有效的电子邮件地址。

对应与 django.db.models.fields.EmailField

签名: EmailField(max_length=None, min_length=None, allow_blank=False)

RegexField:

表示文本,用于验证给定的值是否与某个正则表达式匹配。

对应与 django.forms.fields.RegexField.

签名: RegexField(regex, max_length=None, min_length=None, allow_blank=False)

强制的 regex 参数可以是一个字符串,也可以是一个编译好的 Python 正则表达式对象。

使用 Django 的 django.core.validators.RegexValidator 进行验证。

SlugField:

一个根据模式 [a-zA-Z0-9_-]+ 验证输入的 RegexField

对应与 django.db.models.fields.SlugField.

签名: SlugField(max_length=50, min_length=None, allow_blank=False)

URLField:

一个根据 URL 匹配模式验证输入的 RegexField。完全合格的 URL 格式为 http://<host>/<path>

对应与 django.db.models.fields.URLField. 使用 Django 的 django.core.validators.URLValidator 进行验证。

签名: URLField(max_length=200, min_length=None, allow_blank=False)

UUIDField:

确保输入的字段是有效的 UUID 字符串。to_internal_value 方法将返回一个 uuid.UUID 实例。在输出时,字段将以规范的连字符格式返回一个字符串,例如:

"de305d54-75b4-431b-adb2-eb6b9e546013"

签名: UUIDField(format='hex_verbose')

  • format: 确定 uuid 值的表示形式
  • 'hex_verbose' - 权威的十六进制表示形式,包含连字符: "5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
  • 'hex' - 紧凑的十六进制表示形式, 不包含连字符:"5ce0e9a55ffa654bcee01238041fb31a"
  • 'int' - 128 位整数表示形式:"123456789012312313134124512351145145114"
  • 'urn' - RFC 4122 URN 表示形式: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 修改 format仅影响表示值。所有格式都被 to_internal_value 接受。

5.3:数字字段:

IntegerField:

表示整数。

对应于 django.db.models.fields.IntegerField, django.db.models.fields.SmallIntegerField, django.db.models.fields.PositiveIntegerFielddjango.db.models.fields.PositiveSmallIntegerField

签名: IntegerField(max_value=None, min_value=None)

  • max_value 验证所提供的数字不大于这个值。
  • min_value 验证所提供的数字不小于这个值。

FloatField:

表示浮点。

对应于 django.db.models.fields.FloatField.

签名: FloatField(max_value=None, min_value=None)

  • max_value 验证所提供的数字不大于这个值。
  • min_value 验证所提供的数字不小于这个值。

DecimalField:

表示十进制,由 Python 用 Decimal 实例表示。

对应于 django.db.models.fields.DecimalField.

签名: DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)

  • max_digits 允许的最大位数。它必须是 None 或大于等于 decimal_places 的整数。

  • decimal_places 小数位数。

  • coerce_to_string 如果应返回字符串值,则设置为 True ;如果应返回 Decimal 对象,则设置为 False 。默认值与 COERCE_DECIMAL_TO_STRING settings key 的值相同,除非被覆盖,否则该值将为 True。如果序列化对象返回 Decimal 对象,则最终的输出格式将由渲染器决定。请注意,设置 localize 将强制该值为 True

  • max_value 验证所提供的数字不大于这个值。

  • min_value 验证所提供的数字不小于这个值。

  • localize 设置为 True 以启用基于当前语言环境的输入和输出本地化。这也会迫使 coerce_to_stringTrue 。默认为 False 。请注意,如果你在 settings 文件中设置了 USE_L10N=True,则会启用数据格式化。

  • rounding 设置量化到配置精度时使用的舍入模式。 有效值是 decimal 模块舍入模式。默认为 None

  • 举个栗子:

    若要验证数字到666,精确到 2 位小数,应该使用:
    serializers.DecimalField(max_digits=5, decimal_places=2)
    
  • 这个字段还接受一个可选参数,coerce_to_string。如果设置为 True,则表示将以字符串形式输出。如果设置为 False,则表示将保留为 Decimal 实例,最终表示形式将由渲染器确定。

    如果未设置,则默认设置为与 COERCE_DECIMAL_TO_STRING setting 相同的值,除非另行设置,否则该值为 True

5.4:日期和时间字段:

DateTimeField:

表示日期和时间。

对应于 django.db.models.fields.DateTimeField.

签名: DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)

  • format - 表示输出格式的字符串。如果未指定,则默认为与 DATETIME_FORMAT settings key 相同的值,除非设置,否则将为 'iso-8601'。设置为格式化字符串则表明 to_representation 返回值应该被强制为字符串输出。格式化字符串如下所述。将此值设置为 None 表示 Python datetime 对象应由 to_representation 返回。在这种情况下,日期时间编码将由渲染器确定。
  • input_formats - 表示可用于解析日期的输入格式的字符串列表。 如果未指定,则将使用 DATETIME_INPUT_FORMATS 设置,该设置默认为 ['iso-8601']
DateTimeField 格式化字符串:

格式化字符串可以是明确指定的 Python strftime 格式,也可以是使用 ISO 8601 风格 datetime 的特殊字符串 iso-8601 。(例如 '2013-01-29T12:34:56.000000Z'

当一个 None 值被用于格式化 datetime 对象时,to_representation 将返回,最终的输出表示将由渲染器类决定。

auto_now和 auto_now_add模型字段:

使用 ModelSerializerHyperlinkedModelSerializer 时,请注意,auto_now=Trueauto_now_add=True 的模型字段默认情况下将使用 read_only=True

如果想覆盖此行为,则需要在序列化类中明确声明 DateTimeField。例如:

class CommentSerializer(serializers.ModelSerializer):
    created = serializers.DateTimeField()

    class Meta:
        model = Comment

DateField:

表示日期。

对应于 django.db.models.fields.DateField

签名: DateField(format=api_settings.DATE_FORMAT, input_formats=None)

  • format - 表示输出格式的字符串。如果未指定,则默认为与 DATE_FORMAT settings key 相同的值,除非设置,否则将为 'iso-8601'。设置为格式化字符串则表明 to_representation 返回值应该被强制为字符串输出。格式化字符串如下所述。将此值设置为 None 表示 Python date 对象应由 to_representation 返回。在这种情况下,日期时间编码将由渲染器确定。
  • input_formats - 表示可用于解析日期的输入格式的字符串列表。 如果未指定,则将使用 DATE_INPUT_FORMATS 设置,该设置默认为 ['iso-8601']
DateField格式化字符串:

格式化字符串可以是明确指定的 Python strftime 格式,也可以是使用 ISO 8601 风格 date 的特殊字符串 iso-8601 。(例如 '2013-01-29'

TimeField:

表示时间。

对应于 django.db.models.fields.TimeField

签名: TimeField(format=api_settings.TIME_FORMAT, input_formats=None)

  • format - 表示输出格式的字符串。如果未指定,则默认为与 TIME_FORMAT settings key 相同的值,除非设置,否则将为 'iso-8601'。设置为格式化字符串则表明 to_representation 返回值应该被强制为字符串输出。格式化字符串如下所述。将此值设置为 None 表示 Python time 对象应由 to_representation 返回。在这种情况下,日期时间编码将由渲染器确定。
  • input_formats - 表示可用于解析日期的输入格式的字符串列表。 如果未指定,则将使用 TIME_INPUT_FORMATS 设置,该设置默认为 ['iso-8601']

5.5:选择字段:

ChoiceField:

可以从一个有限的选择中接受值的字段。

如果相应的模型字段包含 choices=… 参数,则由 ModelSerializer 自动生成字段。

签名: ChoiceField(choices)

  • choices - 有效值列表,或 (key, display_name) 元组列表。
  • allow_blank - 如果设置为 True,则空字符串应被视为有效值。如果设置为 False,那么空字符串被认为是无效的并会引发验证错误。默认是 False
  • html_cutoff - 如果设置,这将是 HTML 选择下拉菜单中显示的选项的最大数量。可用于确保自动生成具有非常大可以选择的 ChoiceField,而不会阻止模板的渲染。默认是 None.
  • html_cutoff_text - 指定一个文本指示器,在截断列表时显示,比如在 HTML 选择下拉菜单中已经截断了最大数量的项目。默认就会显示 "More than {count} items…"

Allow_blankallow_null 都是 ChoiceField 上的有效选项,但强烈建议只使用一个而不是两个都用。对于文本选择,allow_blank 应该是首选,allow_null 应该是数字或其他非文本选项的首选。

猜你喜欢

转载自blog.csdn.net/Fe_cow/article/details/93135784