drf serializer 的序列化
drf serializer 的序列化
文章目录
- drf serializer 的序列化
- 1、序列化类 常用字段类 及字段参数
- 1.1、常用字段类
- 1.2、常用字段参数
- 2、 序列化类高级用法之source
- 3、序列化类高级用法之定制序列化字段的两种方式
- 3.1、方式一 演示:
- 2.2、方式二 演示
- 3、反序列化
- 5、模型类序列化器(ModelSerializer))使用
- 6、反序列化之数据校验
- 7、断言 assert
- 作业
- 1、写出book表(带关联关系)5 个接口
- 1.1、Serializer 方法
- 1.2、ModelSerialize方法
- 2、出版社,作者,作者详情 5个接口写完(ModelSerializer好些一些)
1、序列化类 常用字段类 及字段参数
1.1、常用字段类
# BooleanField BooleanField()
# NullBooleanField NullBooleanField()
# CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
# EmailField EmailField(max_length=None, min_length=None, allow_blank=False)
# RegexField RegexField(regex, max_length=None, min_length=None, allow_blank=False)
# SlugField SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
# URLField URLField(max_length=200, min_length=None, allow_blank=False)
# UUIDField UUIDField(format=’hex_verbose’) format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
# IPAddressField IPAddressField(protocol=’both’, unpack_ipv4=False, **options)
# IntegerField IntegerField(max_value=None, min_value=None)
# FloatField FloatField(max_value=None, min_value=None)
# DecimalField DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置
# DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
# DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)
# TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
# DurationField DurationField()
# ChoiceField ChoiceField(choices) choices与Django的用法相同
# MultipleChoiceField MultipleChoiceField(choices)
# FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
# ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
常用字段
CharField
BooleanField
IntegerField
DecimalField
ListField: {name:'lqz',age:19,hobby:['篮球','足球']}
DictField:{name:'lqz',age:19,wife:{'name':'刘亦菲','age':33}}
1.2、常用字段参数
给CharField 字段用的参数
参数名称 | 作用 |
---|---|
max_length
|
最大长度 |
min_lenght
|
最小长度 |
allow_blank
|
是否允许为空 |
trim_whitespace
|
是否允许为空 |
给IntegerField字段用的参数
参数名称 | 作用 |
---|---|
max_value
|
最小值 |
min_value
|
最小值 |
**通用参数 **
参数名称 | 作用 |
---|---|
required
|
表明该字段在反序列化时必须输入,默认True |
default
|
反序列化时使用的默认值 |
allow_null
|
表明该字段是否允许传入None,默认False |
validators
|
该字段使用的验证器【不需要了解】 |
error_messages
|
包含错误编号与错误信息的字典 |
label
|
用于HTML展示API页面时,显示的字段名称 |
help_text
|
用于HTML展示API页面时,显示的字段帮助提示信息 |
重点
参数名称 | 作用 |
---|---|
read_only
|
表明该字段仅用于序列化输出,默认False |
write_only
|
表明该字段仅用于反序列化输入,默认False |
2、 序列化类高级用法之source
修改序列化字段名字
使用source,字段参数,可以指定序列化表中得哪个字段
book_name = serializers.CharField(max_length=8, min_length=3,source='name')
- source指定的可以是字段,也可以是方法,用于重命名
- source可以做跨表查询
演示
class BookSerializer(serializers.Serializer):name_detail = serializers.CharField(max_length=8, min_length=3,source='name')# 或publish_name = serializers.CharField(max_length=8, min_length=3,source='publish.name')# 或xx = serializers.CharField(max_length=8, min_length=3,source='xx') #source的xx表示表模型中得方法
3、序列化类高级用法之定制序列化字段的两种方式
前端显示形式
{"name": "西游记","price": 33,"publish": {name:xx,city:xxx,email:sss}
}
方式一:
在【序列化类】中写SerializerMethodField
publish = serializers.SerializerMethodField()def get_publish(self, obj):# obj 是当前序列化的对象return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}
方式二:
在【表模型】中写方法(又多一些)
def publish_detail(self):return {'name': self.publish.name, 'city': self.publish.city, 'email': self.publish.email}在序列化中取publish_detail=serializers.DictField
在模型类中写逻辑代码,称之为ddd,领域驱动模型
3.1、方式一 演示:
class BookSerializer(serializers.Serializer):name = serializers.CharField(max_length=8, min_length=3)price = serializers.IntegerField(min_value=10, max_value=99)publish_date = serializers.DateField()# publish要序列化成 {name:北京出版社,city:北京,email:2@qq.com}# 方式一:SerializerMethodField必须配合一个方法(get_字段名,需要接受一个参数),方法返回什么,这个字段就是什么publish = serializers.SerializerMethodField()def get_publish(self, obj):# obj 是当前序列化的对象return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}# 练习,用方式一,显示所有作者对象 []authors = serializers.SerializerMethodField()def get_authors(self, obj):res_list = []for author in obj.authors.all():res_list.append({'id': author.id, 'name': author.name, 'age': author.age})return res_list
2.2、方式二 演示
# 表模型中
class Book(models.Model):name = models.CharField(max_length=32)price = models.DecimalField(max_digits=5, decimal_places=2)publish_date = models.DateField(null=True)publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)authors = models.ManyToManyField(to='Author')# 写了个方法,可以包装成数据属性,也可以不包def publish_detail(self):return {'name': self.publish.name, 'city': self.publish.city, 'email': self.publish.email}def author_list(self):res_list = []for author in self.authors.all():res_list.append({'id': author.id, 'name': author.name, 'age': author.age})return res_list
序列化类中
class BookSerializer(serializers.Serializer):name = serializers.CharField(max_length=8, min_length=3)price = serializers.IntegerField(min_value=10, max_value=99)publish_date = serializers.DateField()# 方式二:在表模型中写方法publish_detail = serializers.DictField(read_only=True)# 练习,使用方式二实现,显示所有作者author_list = serializers.ListField(read_only=True)
3、反序列化
序列化和反序列化字段 不一样【】
publish = serializers.CharField(write_only=True)
authors = serializers.ListField(write_only=True)
重写create
使用继承Serializer的序列化类保存需要重写create方法
def create(self, validated_data): # validated_data 校验过后的数据 {"name":"三国1演义","price":19,"publish_date": "2022-09-27","publish":1,"authors":[1,2]}book = Book.objects.create(name=validated_data.get('name'),price=validated_data.get('price'),publish_date=validated_data.get('publish_date'),publish_id=validated_data.get('publish'),)authors = validated_data.get('authors')book.authors.add(*authors)return book
5、模型类序列化器(ModelSerializer))使用
比继承Serializers序列化方法更方便
class BookModelSerializer(serializers.ModelSerializer): #ModelSerializer继承Serializer# 不需要写字段了,字段从表模型映射过来class Meta:model = Book # 要序列化的表模型# fields='__all__' # 所有字段都序列化fields = ['name', 'price', 'publish_date', 'publish', 'authors', 'publish_detail','author_list'] # 列表中有什么,就是序列化哪个字段# 给authors和publish加write_only属性# name加max_len属性extra_kwargs = {'name': {'max_length': 8},'publish': {'write_only': True},'authors': {'write_only': True},}
6、反序列化之数据校验
跟 form数据校验 方法很像
# 字段自己的校验规则-如果继承的是Serializer,写法如下name=serializers.CharField(max_length=8,min_length=3,error_messages={'min_length': "太短了"})-如果继承的是ModelSerializer,写法如下extra_kwargs = {'name': {'max_length': 8, 'min_length': 3, 'error_messages': {'min_length': "太短了"}},}# 局部钩子-如果继承的是Serializer,写法一样-如果继承的是ModelSerializer,写法一样def validate_name(self, name):if name.startswith('sb'):# 校验不通过,抛异常raise ValidationError('不能以sb卡头')else:return name# 全局钩子-如果继承的是Serializer,写法一样-如果继承的是ModelSerializer,写法一样def validate(self, attrs):if attrs.get('name') == attrs.get('publish_date'):raise ValidationError('名字不能等于日期')else:return attrs
局部钩子
继承的是Serializer 与继承ModelSerializer写法一样
def validate_name(self, name):if name.startswith('sb'):# 校验不通过,抛异常raise ValidationError('不能以sb卡头')else:return name
全局钩子
继承的Serializer与继承ModelSerializer 写法一样
def validate(self, attrs):if attrs.get('name') == attrs.get('publish_date'):raise ValidationError('名字不能等于日期')else:return attrs
7、断言 assert
在框架源码中,大量使用断言
断言,作用的判断,断定一个变量必须是xx,如果不是就报错
assert :
普通写法
name = 'lqz1'
if not name == 'ming':raise Exception('name不等于ming')
print('程序执行完了')
断言写法
name = 'lqz1'
assert name == 'lqz', 'name不等于lqz'
print('程序执行完了')
作业
写出book表(带关联关系)5 个接口
Serializer
ModelSerializer(简单,不用重写create和update)
name最大8,最小3,名字中不能带sb
price最小9,最大199,不能为66
1、写出book表(带关联关系)5 个接口
1.1、Serializer 方法
serializer.py
from rest_framework import serializers
from app01.models import Book,Author,Author_Detail,Publishfrom rest_framework.exceptions import ValidationErrorclass BookSerializer(serializers.Serializer):name = serializers.CharField(max_length=8,min_length=3)price = serializers.IntegerField(max_value=199,min_value=9)publish_date = serializers.DateField()publish_out = serializers.SerializerMethodField(read_only=True,)def get_publish_out(self, obj):return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}author_out = serializers.SerializerMethodField(read_only=True)def get_author_out(self, obj):author_list = []for author_obj in obj.author.all():author_list.append({'name': author_obj.name, 'age': author_obj.age})return author_listpublish = serializers.IntegerField(write_only=True)author = serializers.ListField(write_only=True)def validate_price(self,price):if price == 66:raise ValidationError('不饿能为66')else:return pricedef validate_name(self,name):if name.count('sb')>=1:raise ValidationError('名字中有铭感词汇')else:return namedef create(self, validated_data):book=Book.objects.create(name=validated_data.get('name'),price=validated_data.get('price'),publish_date=validated_data.get('publish_date'),publish_id=validated_data.get('publish'),)author_list = validated_data.get('author')book.author.add(*author_list)return bookdef update(self, instance, validated_data):instance.name = validated_data.get('name')instance.price = validated_data.get('price')instance.publish_date = validated_data.get('publish_date')instance.publish_id = validated_data.get('publish')instance.author.set(validated_data.get('author'))instance.save()return instance
view.py
from app01.models import Bookfrom rest_framework.views import APIView
from rest_framework.response import Response
from app01.serializer import BookSerializerclass BookView(APIView):def get(self, request):book = Book.objects.all()ser = BookSerializer(instance=book, many=True)return Response(ser.data)def post(self, request):ser = BookSerializer(data=request.data)if ser.is_valid():ser.save()return Response(ser.data)else:return Response(ser.errors)class Book_View(APIView):def get(self,request,pk):book_obj = Book.objects.filter(pk=pk).first()ser = BookSerializer(instance=book_obj)return Response(ser.data)def put(self, request, pk):book_obj = Book.objects.filter(pk=pk).first()ser = BookSerializer(instance=book_obj, data=request.data)if ser.is_valid():ser.save()return Response(ser.data)else:return Response(ser.errors)def delete(self, request, pk):book_obj = Book.objects.filter(pk=pk).delete()return Response()
1.2、ModelSerialize方法
serializer.py
from rest_framework import serializers
from app01.models import Book,Author,Author_Detail,Publishfrom rest_framework.exceptions import ValidationErrorclass BookModelSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['name', 'price', 'publish_date', 'publish', 'author', 'publish_int', 'author_li']extra_kwargs = {'name':{'max_length':8,'min_length':3,'error_messages':{'max_length':'名字太长了','min_length':'名字太短了'}},'price':{'max_value':199,'min_value':9,'error_messages':{'max_value':'最大值为199','min_value':'最小值为9',}},'publish':{'write_only':True},'author':{'write_only':True},}def validate_price(self, price):if price == 66:raise ValidationError('不饿能为66')else:return pricedef validate_name(self, name):if name.count('sb')>=1:raise ValidationError('名字中有铭感词汇')else:return name
views.py
from app01.models import Bookfrom rest_framework.views import APIView
from rest_framework.response import Response
from app01.serializer import BookModelSerializerclass BookView(APIView):def get(self, request):book = Book.objects.all()ser = BookModelSerializer(instance=book, many=True)return Response(ser.data)def post(self, request):ser = BookModelSerializer(data=request.data)if ser.is_valid():ser.save()return Response(ser.data)else:return Response(ser.errors)class Book_View(APIView):def get(self,request,pk):book_obj = Book.objects.filter(pk=pk).first()ser = BookModelSerializer(instance=book_obj)return Response(ser.data)def put(self, request, pk):book_obj = Book.objects.filter(pk=pk).first()ser = BookModelSerializer(instance=book_obj, data=request.data)if ser.is_valid():ser.save()return Response(ser.data)else:return Response(ser.errors)def delete(self, request, pk):book_obj = Book.objects.filter(pk=pk).delete()return Response()
2、出版社,作者,作者详情 5个接口写完(ModelSerializer好些一些)
class Publish_Mser(serializers.ModelSerializer):class Meta:model = Publishfields = ['name','city','email',]class Author_Mser(serializers.ModelSerializer):class Meta:model = Authorfields = ['name','age']class Author_Detail_MSer(serializers.ModelSerializer):class Meta:model = Author_Detailfields = ['phone','addr']
drf serializer 的序列化相关推荐
- DRF批量修改序列化器使用
需求:用户将选择型问答提交,前端返回所有问答数据,将问答数据批量修改入到数据库中 model class QuestionnairQA(BaseModel):question_choices = ( ...
- 【DRF框架】序列化组件——字段验证
单个字段的验证 1.在序列化器里定义校验字段的钩子方法 validate_字段 2.获取字段的数据 3.验证不通过,抛出异常 raise serializers.ValidationError( ...
- Django框架(十九)—— drf:序列化组件(serializer)
序列化组件 # 模型层 from django.db import modelsclass Book(models.Model): nid = models.AutoField(primary_key ...
- 快速上手Django(六) -Django之Django drf 序列化器Serializer类
文章目录 快速上手Django(六) -Django之Django drf 序列化器Serializer类 1. 背景 2. 使用思路 3. 代码demo 4. [重要]序列化类 ModelSeria ...
- Django框架深入了解_02(DRF之序列化、反序列化)
阅读目录 序列化:将Python对象准换成json格式的字符串,反之即为反序列化 DRF的序列化使用过程: 使用drf的序列化组件 -1 新建一个序列化类继承Serializer -2 在类中写要序列 ...
- Django REST Framework教程(4): 玩转序列化器(Serializer)
在前面的文章中我们以博客为例,自定义了一个简单的 ArticleSerializer 类, 并分别以函数视图(FBV)和基于类的视图(CBV)编写了博客文章列表资源和单篇文章资源的API,支持客户端以 ...
- 谈谈Django REST Framework(DRF)中的序列化器
摘要 Django REST Framework(DRF)是一个强大的工具,可以帮助我们构建和处理RESTful API.其中的序列化器(Serializers)是其核心组件之一,它允许我们快速有效地 ...
- Django DRF 序列化类
文章目录 1. 序列化类 Serializer 1.1 Serializer 基本使用 1.2 定义序列化类 1.3 创建 Serializer 对象 1.4 序列化 1.5 反序列化 1.6 钩子函 ...
- 1. DRF 序列化组件
0. 环境创建 * 1. 新建一个项目 * 2. 修改 tempaltes路径问题 # 修改模板文件路径拼接问题 'DIRS': [BASE_DIR, 'templates'] * 3. 在app01 ...
最新文章
- git查看linux内核log,linux查看用户、内核、CPU信息
- springsecurity文档_今天学了springsecurity
- 【Elasticsearch】搜索自己想要的东西与注释文本(字符串)插件
- 工程变更(ENGINEERING CHANGE)
- java mongo忽略大小写_Java Spring Mongo排序忽略大小写问题
- numpy.linalg——线性代数运算
- hadoop mapper从源码开始 详解
- 非参数统计单样本非参数检验之Kolmogorov-Smirnov检验
- 产品经理技能学习:流程图绘制及规范
- 2000款商务通用PPT模板免费下载
- 2021年危险化学品经营单位安全管理人员报名考试及危险化学品经营单位安全管理人员考试资料
- 串口屏储存器不够,自己扩展怎么操作?
- 单元测试中的 AAA 规则
- 转:理想主义终结年代的七种兵器
- python生成递归json_python函数、递归、json模块操作
- 【年度总结】满船清梦压星河
- Odoo14问题总结——模块视图不显示
- rkwatchgod 看门狗配置,rockchip
- mysql比较两个数函数_mysql函数之比较函数(2)
- 【小程序源码】笑话与趣图框架
热门文章
- java 实训项目_实训方案(JavaWeb项目实训)-
- OpenCV学习——直方图、边缘检测、模板匹配以及霍夫变化
- merra-2气溶胶、OMI大气产品数据处理阶段摸索中~~~
- 监狱应急指挥联动系统,牢筑安全防线
- 怎么用计算机编写圆的面积,圆的面积教学反思八篇
- Vikinger v1.9.3汉化版WordPress模板主题
- MFC 数据有效机制(DDV)
- ClientDataSet的用法(转)
- Cause: java.sql.SQLNonTransientConnectionException
- java计算机毕业设计计算机数字逻辑在线学习系统MyBatis+系统+LW文档+源码+调试部署