DRF 外键字段深度查询优化、ListSerializer辅助完成群改
一、Response封装
用def自带的response模块返回数据需要data和status等参数,就算有相同的response也需要重新写一遍,这样显得很不方便。
因此我们可以将response模块进行二次封装,减少一些代码的重复书写,这样就可以使我们的工作量变小。
方法:
在应用文件夹中重新写一个response.py文件,专门用来二次封装drf的response模块。
class APIResponse(Response):
def __init__(self, status=0, msg='ok', results=None, http_status=None,headers=None, exception=False, content_type=None, **kwargs):
# 将status、msg、results、kwargs格式化成data
data = {
'status': status,
'msg': msg,
}
# results只要不为空都是数据:False、0、'' 都是数据 => 条件不能写if results
if results is not None:
data['results'] = results
# 将kwargs中额外的k-v数据添加到data中
data.update(**kwargs)
super().__init__(data=data, status=http_status, headers=headers, exception=exception, content_type=content_type)
二、外键字段深度查询
1、序列化配置exclude、depth
必须有子序列化类配合,不能反序列化了。
只能在序列化中使用。
字段名必须是外键(正向反向)字段。
- 因为相对于自定义序列化外键字段,自定义序列化字段是不能参与反序列化的,而子序列化必须为外键名,所以就无法入库。
在外键关联数据是多条时,需要明确many=True。
是单向操作,因为作为子系列的类必须写在上方,所以不能产生逆方向的子序列化。
class PublishModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Publish
# fields = ['name', 'address', 'books']
# 了解配置
# fields = '__all__' # 所有字段
exclude = ['name'] # 排除字段
depth = 2 # 自动深度,值代表深度次数,但是被深度的外键采用__all__,显示所有字段
2、模型层函数、插拔式字段查询
设置模型表中需要进行序列化和反序列化的字段(容器,列表或元组)。
并且容器中的名称可以映射到模型类中不存在任何参数的属性或方法,通过这种特性可以完成自定义字段的插拔式设计。
# models.py
class Car(models.Model):
name = models.CharField(max_length=64,unique=True)
price = models.DecimalField(max_digits=10,decimal_places=2)
image = models.ImageField(upload_to='img',default='img/default.jpg')
brand = models.CharField(max_length=32,default='unknown')
@property # 可以不写
def image_path(self): # 该方法不能携带参数
return f'{settings.BASE_URL}{settings.MEDIA_URL}{self.image}'
# serializer.py
class CarModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Car
fields = [
'name','price','image_path','brand'
]
三、listserializer辅助类
ListSerializer类能够序列化和一次验证多个对象。你通常不需要直接使用ListSerializer,而是应该在实例化一个序列化器时简单地传递一个many=True参数。
当一个序列化器在带有many=True选项被序列化时,将创建一个ListSerializer实例。该序列化器类将成为ListSerializer类的子类。
当你要自定义多个对象的更新行为(群改)时,你需要手动定制ListSerializer类的一些行为。
可以通过使用序列化器类的Meta类下面的list_serializer_class选项来修改当many=True时正在使用的类。
# 多表操作
class CarListSerializer(serializers.ListSerializer):
# 自定义的群增群改辅助类,没有必要重写create方法
def create(self, validated_data):
return super().create(validated_data)
def update(self, instance_list, validated_data_list):
return [
self.child.update(instance_list[index], attrs) for index, attrs in enumerate(validated_data_list)
]
# 汽车表序列化
class CarModelSerializer(serializers.ModelSerializer):
# 通过SerializerMethodField设置的字段为只读字段
car_color = serializers.SerializerMethodField()
def get_car_color(self,obj):
return obj.get_color_display()
re_brand = serializers.CharField(
write_only=True,
error_messages={
'required':'re_brand为必填字段!'
}
)
class Meta: # 声明
# 绑定需要进行序列化和反序列化的模型表
model = models.Car
# 设置模型表中需要进行序列化和反序列化的字段(容器,列表或元组)。
# 并且容器中的名称可以映射到模型类中不存在任何参数的属性或方法,
# 通过这种特性可以完成自定义字段的插拔式设计
fields = [
'name','car_color','price','image_path','brand','re_brand'
]
read_only_fields = ['car_color','image_path']
# 设置额外的序列化与反序列化的规则
extra_kwargs = {
'name':{
'min_length':2,
'max_length':10,
'error_messages':{
'min_length': '太短',
'max_length': '太长',
}
}
}
def validate(self, attrs):
brand = attrs.get('brand')
re_brand = attrs.pop('re_brand',False)
if not brand == re_brand:
raise serializers.ValidationError({'re_brand':'两次品牌不一致!'})
return attrs
DRF 外键字段深度查询优化、ListSerializer辅助完成群改的更多相关文章
- 01.drf文档及外键字段反序列化
一 安装drf 1.1 安装库 pip install djangorestframework pip install markdown # Markdown support for the brow ...
- Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询
Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...
- MS SQL巡检系列——检查外键字段是否缺少索引
前言感想:一时兴起,突然想写一个关于MS SQL的巡检系列方面的文章,因为我觉得这方面的知识分享是有价值,也是非常有意义的.一方面,很多经验不足的人,对于巡检有点茫然,不知道要从哪些方面巡检,另外一方 ...
- 基于MVC4+EasyUI的Web开发框架经验总结(9)--在Datagrid里面实现外键字段的转义操作
我们在使用EasyUI的时候,很多情况下需要使用到表格控件datagrid,这个控件控件非常强大,使用起来很简洁,但是我在使用中,发现对于一个表里面的外键字段进行转义,并显示引用表的一些名称的操作,却 ...
- django模型中, 外键字段使用to_filed属性 指定到所关联主表的某个字段
在django项目的开发过程中,在设计模型时一开始将主键设置成了一个自定义的字段,但是在创建搜索索引时却发现必须要存在一个id的字段,并且为主键(不知道是否是项目一开始就这样配置的原因), 但此时表结 ...
- (转)基于MVC4+EasyUI的Web开发框架经验总结(9)--在Datagrid里面实现外键字段的转义操作
http://www.cnblogs.com/wuhuacong/p/3872890.html 我们在使用EasyUI的时候,很多情况下需要使用到表格控件datagrid,这个控件控件非常强大,使用起 ...
- day08 外键字段的增删查改
day08 外键字段的增删查改 今日内容概要 外键字段的增删查改 正反向查询的概念 基于对象的跨表查询(子查询) 基于双下划线的跨表查询(连表操作) 聚合查询与分组查询 F查询和Q查询 前提准备 cl ...
- django【ORM】 通过外键字段找对应类
两个方法其实是一种,用哪个都行,看实例: 方法一: 从list_filter中的字符串,找到model对象的字段,然后得到这个外键对应的类 循环,把list_filter中对应的类所有对象 方法二 ...
- MySql数据库在表中添加新字段,设置主键,设置外键,字段移动位置,以及修改数据库后如何进行部署和维护的总结
1,为当前已有的表添加新的字段 alter table student add studentName varchar(20) not null; 2,为当前已有的表中的字段设置为主键自增 alter ...
随机推荐
- Flink-v1.12官方网站翻译-P010-Fault Tolerance via State Snapshots
通过状态快照进行容错 状态后台 Flink管理的键控状态是一种碎片化的.键/值存储,每项键控状态的工作副本都被保存在负责该键的任务管理员的本地某处.操作员的状态也被保存在需要它的机器的本地.Flink ...
- DolphinScheduler1.3.2源码分析(二)搭建源码环境以及启动项目
前置依赖组件安装 找一台服务器,或者本地的虚拟机,然后在服务器上安装好jdk,zookeeper,mysql. 1.源码调试环境搭建 源码环境搭建可以参考DolphinScheduler官方网站的开发 ...
- docker(4)解决pull镜像速度缓慢
前言 上一篇讲到pull 镜像,但是pull镜像的时候下拉的速度实在感人,有什么解决办法吗?我们只需将docker镜像源修改为国内的 将docker镜像源修改为国内的: 在 /etc/docker/d ...
- springboot中扩展ModelAndView实现net mvc的ActionResult效果
最近在写spring boot项目,写起来感觉有点繁琐,为了简化spring boot中的Controller开发,对ModelAndView进行简单的扩展,实现net mvc中ActionResul ...
- vue-cli3移动端自适应配置 Vant组件库
module.exports = { presets: [ '@vue/app' ], plugins: [ ['import', { libraryName: 'vant', libraryDire ...
- GPLT L2-024 部落 (并查集)
N ≤ 104,输入如下数据如果没有路径压缩可能会超时. 10000 2 1 2 2 3 4 2 5 6 -- 2 9997 9998 2 9999 10000 2 9999 9997 -- 2 5 ...
- 【noi 2.7_413】Calling Extraterrestrial Intelligence Again(算法效率--线性筛素数+二分+测时)
题意:给3个数M,A,B,求两个质数P,Q.使其满足P*Q<=M且A/B<=P/Q<=1,并使P*Q最大.输入若干行以0,0,0结尾. 解法:先线性筛出素数表,再枚举出P,二分出对应 ...
- tesseract-ocr的安装及使用pycharm来运行
1.可以在:http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe 下载一个exe文件,然后直接按照提 ...
- Codeforces Round #570 (Div. 3) E. Subsequences (easy version) (搜索,STL)
题意:有一长度为\(n\)的字符串,要求得到\(k\)不同的它的子序列(可以是空串),每个子序列有\(|n|-|t|\)的贡献,求合法情况下的最小贡献. 题解:直接撸个爆搜找出所有子序列然后放到set ...
- 避坑!js正确地使用fill()初始化二维数组
先介绍一下坑 fill()方法都知道,填充数组 比如: let a = new Array(5).fill(0); console.log(a); // 输出结果为[0, 0, 0, 0, 0] 当我 ...