Django-drf架构 序列化的详解
一、为什么使用序列化器?
序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型,然后可以将它们轻松地呈现为 JSON
,XML
或其他内容类型。
序列化器还提供反序列化,在首次验证传入数据之后,可以将解析的数据转换回复杂类型。
二、创建模型类:
# -*- 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 # 资格证书:MAT,CFE等
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')
-
总结:
fields
和exclude
属性中的名称通常映射到模型类的模型字段。或者
fields
选项中的名称可以映射成属性或方法
。而不会变成模型类中的参数。从版本 3.3.0 开始,必须提供其中一个属性
fields
或exclude
。
-
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_length
, min_length
验证(或限定)文本的长短。
对应与 django.db.models.fields.CharField
或 django.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=True
和 allow_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.PositiveIntegerField
和 django.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_string
为True
。默认为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
表示 Pythondatetime
对象应由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模型字段:
使用 ModelSerializer
或 HyperlinkedModelSerializer
时,请注意,auto_now=True
或 auto_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
表示 Pythondate
对象应由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
表示 Pythontime
对象应由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_blank
和 allow_null
都是 ChoiceField
上的有效选项,但强烈建议只使用一个而不是两个都用。对于文本选择,allow_blank
应该是首选,allow_null
应该是数字或其他非文本选项的首选。