一、什么是序列化
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程:在序列化期间,对象将其当前状态写入到临时或持久性存储区。
以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
Rest_FrameWork 中的 序列化组件 是将 request的对象更好的利用,同时可以接受不同的数据类型。
二、序列化对应的Filed:(序列化接受的数据格式)
- Core arguments:
read_only
write_only
required
default
allow_null
source
validators
error_messages
label
help_text
initial
style
- Boolean fields BooleanFieldNullBooleanField
- String fields CharFieldEmailFieldRegexFieldSlugFieldURLFieldUUIDFieldFilePathFieldIPAddressField
- Numeric fields IntegerFieldFloatFieldDecimalField
- Date and time fields DateTimeFieldDateFieldTimeFieldDurationField
- Choice selection fields ChoiceFieldMultipleChoiceField
- File upload fields Parsers and file uploads.FileFieldImageField
- Composite fields ListFieldDictFieldHStoreFieldJSONField
- Miscellaneous fields ReadOnlyFieldHiddenFieldModelFieldSerializerMethodField
三、定义一个序列化文件
3.1 了解接受什么内容!
序列化文件 接受的内容如下:需要接受这个comment对象
from datetime import datetime
class Comment(object):
def __init__(self, email, content, created=None):
self.email = email
self.content = content
self.created = created or datetime.now()
comment = Comment(email='leila@example.com', content='foo bar')
3.2 描述serializer filed
from rest_framework import serializers
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
3.3 序列化与反序列化
serializer = CommentSerializer(comment)
serializer.data
# {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'} #打印步骤一
from rest_framework.renderers import JSONRenderer
json = JSONRenderer().render(serializer.data)
json
# b'{"email":"leila@example.com","content":"foo bar","created":"2016-01-27T15:17:10.375877"}' #序列化 JSON格式
import io
from rest_framework.parsers import JSONParser
stream = io.BytesIO(json)
data = JSONParser().parse(stream) #反序列化成obj格式
四、save instances
什么是saving instances,即保存实例,对象即实例,顾名思义,如何将对象数据 序列化保存在数据库中,,等等
4.1:一个例子
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
#save instance
def create(self, validated_data):
return Comment(**validated_data) #返回实例数据
def update(self, instance, validated_data):
instance.email = validated_data.get('email', instance.email)
instance.content = validated_data.get('content', instance.content)
instance.created = validated_data.get('created', instance.created)
return instance
4.2:如果你想将序列化数据保存在django 的model中,再存入数据库
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
def create(self, validated_data):
return Comment.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.email = validated_data.get('email', instance.email)
instance.content = validated_data.get('content', instance.content)
instance.created = validated_data.get('created', instance.created)
instance.save()
return instance
4.3:上面的代码描述了如何 去保存一个序列化数据的实例,运行以下代码执行上述代码:
# .save() will create a new instance. #保存一个新的实例
serializer = CommentSerializer(data=data)
# .save() will update the existing `comment` instance. #如果实例存在,则更新数据
serializer = CommentSerializer(comment, data=data)
serializer.save()
4.4:为什么选择serializer.save() 来执行代码?下面是serializer.save()的源码
serializer.py
def save(self,**kwargs):
...
if self.instance is not None:
self.instance = self.update(self,instance, validated_data)
else:
self.instance = self.create(validate_data)
return self.instance
4.5 部分更新
serializer = CommentSerializer(comment, data={'content': 'foo bar'}, partial=True)
五、MORDELserializers
一个更加方便的Filed表示方式,(只是更加方便!!) #base on the model,include defalt function .create .update
5.1 一个例子
class AccountSerializer(serializers.ModelSerializer): #继承的是ModelSerializer
class Meta:
model = Account #import the Acc model
fields = ['id', 'account_name', 'users', 'created']
5.2 指定相关的filed
#fields='__all__' #model 全部字段
#
exclude = ['users'] #排除某个字段
5.3 添加extra filed
class AccountSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
groups = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = Account
5.4 指定只读字段
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['id', 'account_name', 'users', 'created']
read_only_fields = ['account_name']
#指定其他参数可以通过以下例子了解,和read_only_field一样,定义方式通过dict方式
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['email', 'username', 'password']
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User(
email=validated_data['email'],
username=validated_data['username']
)
user.set_password(validated_data['password'])
user.save()
return user
5.5 ModelSerializer 和 hyperlinkModelSerializers 区别
基本上是一样的,MS通过主键方式表示关系, HLMS通过超链接方式表示关系
六、处理嵌套信息
6.1 嵌套nested对象obj
class CommentSerializer(serializers.Serializer):
user = UserSerializer(required=False) # many anomyous
edits = EditItemSerializer(many=True) # A nested list of 'edit' items.
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
####test
serializer = CommentSerializer(data={'user': {'email': 'foobar', 'username': 'doe'}, 'content': 'baz'})
serializer.is_valid()
# False
serializer.errors
# {'user': {'email': ['Enter a valid e-mail address.']}, 'created': ['This field is required.']}
6.2 writable nested representations
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ['username', 'email', 'profile']
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(**validated_data)
Profile.objects.create(user=user, **profile_data)
return user
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile')
# Unless the application properly enforces that this field is
# always set, the follow could raise a `DoesNotExist`, which
# would need to be handled.
profile = instance.profile
instance.username = validated_data.get('username', instance.username)
instance.email = validated_data.get('email', instance.email)
instance.save()
profile.is_premium_member = profile_data.get(
'is_premium_member',
profile.is_premium_member
)
profile.has_support_contract = profile_data.get(
'has_support_contract',
profile.has_support_contract
)
profile.save()
return instance