一 自定义反序列化字段
# 一些只参与反序列化的字段,但是不是与数据库关联的
# 在序列化类中规定,并在校验字段时从校验的参数字典中剔除
class PublishModelSerializer(serializers.ModelSerializer):
# 自定义不入库的 反序列化 字段
re_name = serializers.CharField(write_only=True)
class Meta:
model = models.Publish
fields = ('name', 're_name', 'address')
def validate(self, attrs):
name = attrs.get('name')
re_name = attrs.pop('re_name') # 剔除
if name != re_name:
raise serializers.ValidationError({'re_name': '确认名字有误'})
return attrs
二 自定义反序列化字段(详细见项目中使用沙箱支付宝文章)
from rest_framework import serializers
from . import models
class OrderModelSerializer(serializers.ModelSerializer):
# 自定义不入库字段
subject_id = serializers.CharField(write_only=True)
class Meta:
model = models.Order
# 商品名 课程id 总价 订单号 支付类型 下单用户
fields = ('subject','subject_id','total_amount','out_trade_no','pay_type','user')
extra_kwargs = {
'pay_type': {
'required': True
},
'total_amount': {
'required': True
}
}
# 由于create进行了pop,所以validate不进行pop没有问题。
# def validate(self, attrs):
# course_id =attrs.pop('subject_id')
# print(attrs,'校验')
# return attrs
# 也就是说多对多需要重写create
# 不考虑购物车逻辑 只考虑单课程
# 如果需要处理订单详情,前台一定要提供 课程主键(一个或多个)
# 需要重写create方法:1)产生Order表对象 2)产生OrderDetail表对象 => 购物车逻辑
# 需求可拓展:UserCourse user course
def create(self, validated_data):
# 在准备入库这个位置pop也行
print(validated_data,'准备入库')
course_id =validated_data.pop('subject_id')
price =validated_data.get('total_amount')
order_obj = models.Order.objects.create(**validated_data)
# 多对多增加的时候直接对应id最方便。
order_detail = models.OrderDetail.objects.create(order_id=order_obj.id,course_id=course_id,price=price,real_price=price)
return order_obj
模型类中自定义序列化深度
# model类中自定义插拔的外键序列化字段,可以采用外键关联表的序列化类来完成深度查询
class Book(BaseModel):
# ...
@property
def publish_detail(self):
from . import serializers
data = serializers.PublishModelSerializer(self.publish).data
return data