Python 学习笔记(十六)--Django REST Framework之serializers
1.序列化组件介绍
序列化:序列化器会把模型对象转换成字典,经过response以后变成json字符串。
反序列化:把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型。反序列化,可以完成数据校验功能。
2.引入方式
from rest_framework import serializers
3.类的方法和属性
4.序列化类的使用
(1)序列化类,继承 serializers.Serializer (或 serializers.ModelSerializer);
(2)在类中,
为 serializers.Serializer是,明确需要序列化的字段(逐一指明需要的字段);
为 serializers.ModelSerializer,明确 class Meta: 信息。
(3)在视图类中使用:导入序列化类,把要序列化的对象传入, 实例化得到序列化类的对象。【要序列化谁,就把谁传过来,其实就是调用类的__init__,看源码是需注意:这个方法来自父类BaseSerializer】
(4)序列化类的对象.data是一个字典(注意:不是json)。
(5)使用rest_framework.response中的Response,会以Json的形式把字典里面的数据返回。 from rest_framework.response import Response 【如果不使用这个Response,就需要使用JsonResponse (from django.http import JsonResponse)】
5.序列化类的常见字段类型
serializers.CharField()
serializers.IntegerField()
serializers.IntegerField()
serializers.BooleanField()
serializers.ChoiceField()
serializers.JSONField()
7.数据验证(一般用在反序列化)
Serializer中的validate方法:
def validate(self, attrs): return attrs
父类BaseSerializer有个is_valid方法
def is_valid(self, raise_exception=False): assert hasattr(self, 'initial_data'), ( 'Cannot call `.is_valid()` as no `data=` keyword argument was ' 'passed when instantiating the serializer instance.' ) if not hasattr(self, '_validated_data'): try: self._validated_data = self.run_validation(self.initial_data) except ValidationError as exc: self._validated_data = {} self._errors = exc.detail else: self._errors = {} if self._errors and raise_exception: raise ValidationError(self.errors) return not bool(self._errors)
is_valid 返回true 表示验证通过。
注意:不能直接对象.save() , 否则会报错 --NotImplementedError: 'update()' must be implemented。
8.报错原因
Serializer中没有save方法,只是父类BaseSerializer有个save方法.
def save(self, **kwargs): assert hasattr(self, '_errors'), ( 'You must call `.is_valid()` before calling `.save()`.' ) assert not self.errors, ( 'You cannot call `.save()` on a serializer with invalid data.' ) # Guard against incorrect use of `serializer.save(commit=False)` assert 'commit' not in kwargs, ( "'commit' is not a valid keyword argument to the 'save()' method. " "If you need to access data before committing to the database then " "inspect 'serializer.validated_data' instead. " "You can also pass additional keyword arguments to 'save()' if you " "need to set extra attributes on the saved model instance. " "For example: 'serializer.save(owner=request.user)'.'" ) assert not hasattr(self, '_data'), ( "You cannot call `.save()` after accessing `serializer.data`." "If you need to access data before committing to the database then " "inspect 'serializer.validated_data' instead. " ) validated_data = {**self.validated_data, **kwargs} if self.instance is not None: self.instance = self.update(self.instance, validated_data) assert self.instance is not None, ( '`update()` did not return an object instance.' ) else: self.instance = self.create(validated_data) assert self.instance is not None, ( '`create()` did not return an object instance.' ) return self.instance
父类中还有个update()
def update(self, instance, validated_data): raise NotImplementedError('`update()` must be implemented.')
就是这个汇报的错误。
所以,需要在序列化类中,重新这个update方法。重写时,需要注意,instance代表的是序列化类对象,validated_data是校验后的数据。赋值后,不要忘记保存和返回。
即
instance.save() return instance
9. 有必要看下父类BaseSerializer的代码,特别是__init__,需要留意的是data参数。
在视图类中,一般通过 序列化类(instance=model的对象, data=request.data),这种格式进行反序列化。
class BaseSerializer(Field): """ The BaseSerializer class provides a minimal class which may be used for writing custom serializer implementations. Note that we strongly restrict the ordering of operations/properties that may be used on the serializer in order to enforce correct usage. In particular, if a `data=` argument is passed then: .is_valid() - Available. .initial_data - Available. .validated_data - Only available after calling `is_valid()` .errors - Only available after calling `is_valid()` .data - Only available after calling `is_valid()` If a `data=` argument is not passed then: .is_valid() - Not available. .initial_data - Not available. .validated_data - Not available. .errors - Not available. .data - Available. """ def __init__(self, instance=None, data=empty, **kwargs): self.instance = instance if data is not empty: self.initial_data = data self.partial = kwargs.pop('partial', False) self._context = kwargs.pop('context', {}) kwargs.pop('many', None) super().__init__(**kwargs)
10. 通过 钩子函数 丰富验证
局部钩子
通过 validate_字段名(self,接受一个参数), 定义一个钩子函数,丰富对字段的验证。
全局钩子
就是重写serializers.Serializer 中的 validate 方法
def validate(self, attrs): return attrs
11.举例(重新update+钩子函数)
class UserDetailSerializer(serializers.ModelSerializer): def update(self, instance, validated_data): for attr, value in validated_data.items(): if attr == "password": instance.set_password(value) elif attr in ("groups", "user_permissions", "resource_group"): getattr(instance, attr).set(value) else: setattr(instance, attr, value) instance.save() return instance def validate_password(self, password): try: validate_password(password) except ValidationError as msg: raise serializers.ValidationError(msg) return password class Meta: model = Users fields = "__all__" extra_kwargs = { "password": {"write_only": True, "required": False}, "username": {"required": False}, }
例子来自:https://gitee.com/rtttte/Archery/blob/master/sql_api/serializers.py
热门相关:邪王独宠:纨绔异能妃 写给鼹鼠先生的情书 魔葫 陆鸣至尊神殿 我有一张沾沾卡