ORM高阶补充:only, defer,select_related
Queryset官方文档:https://docs.djangoproject.com/en/1.11/ref/models/querysets/
1、需求1:只取某n列
1、方法1:values
2、方法2:values_list
3、方法3:only,defer
# 需求1:只取某n列
# 推荐 方法3:only class Test1View(APIView):
def get(self, request, *args, **kwargs):
"""只取某n列""" # 方法1: values 返回值:queryset=[ {1, 'alex'}, {2, 'jack'}]
queryset = User.objects.all().values('id', 'username')
print(queryset, type(queryset)) # <class 'django.db.models.query.QuerySet'> ser = UserSerializer(instance=queryset, many=True)
print(ser, type(ser)) # <class 'rest_framework.serializers.ListSerializer'> print(ser.data, type(ser.data)) # <class 'rest_framework.utils.serializer_helpers.ReturnList'>
return Response(ser.data) # 方法2:values_list 返回值:queryset=[ (1, 'alex'), (2, 'jack')]
queryset = User.objects.all().values_list('id', 'username')
print(queryset, type(queryset)) ser = UserSerializer(instance=queryset, many=True)
print(ser, type(ser)) # 取数据error
# print(ser.data, type(ser.data))
return Response({}) # 推荐
# 方法3:only defer 返回值:queryset=[obj,obj] [<User: alex>, <User: jack>]
queryset = User.objects.all().only('id', 'username')
# queryset = User.objects.all().defer('username') # 排除某几个
print(queryset, type(queryset)) # 取值
for item in queryset:
print(item.id,item.username) # tip:only中没有age,可以取到age (不推荐)
# 1 alex # ser = UserSerializer(instance=queryset, many=True)
# print(ser.data, type(ser.data))
return Response({})
2、需求2: 打印所有用户姓名以及部门名称
1、方法1:all+跨表 (性能低)
2、方法2:主动创建关联关系 select_related:仅支持one2many
# b. 需求: 打印所有用户姓名以及部门名称
# https://docs.djangoproject.com/zh-hans/2.2/ref/models/querysets/#select-related class TestView(APIView):
def get(self, request, *args, **kwargs):
# 方法1:性能低 all() + 跨表
result = User.objects.all().values('username', 'dp__title') # 10次
# select * from user
for item in result:
print(item['username'], item['dp__title']) # 1次 # get + 跨表 只取一个
u = User.objects.get(id=1)
dpart = u.dp
title = dpart.title
print(u.username, title) return Response({}) # 方法2:主动创建关联关系
result = User.objects.all().select_related('dp')
# select * from user left join depart on user.dp_id = depart.id
print(result,type(result))
for item in result:
print(item.username, item.dp.title)
return Response({})
3、方法3:prefetch_related:2次单表查询,支持many2many
示例:
class Depart(models.Model): 5个部门
title = models.CharField(...) class User(models.Model): 10个用户
name = models.CharField(...)
email = models.CharField(...)
dp = models.FK(Depart)
1.以前的你:11次单表查询 result = User.objects.all()
for item in result:
print(item.name,item.dp.title) 2. seleted_related,主动做连表查询(1次链表) result = User.objects.all().seleted_related('dp')
for item in result:
print(item.name,item.dp.title) 问题:如果链表多,性能越来越差。
3. prefetch_related:2次单表查询
# select * from user ;
# 通过python代码获取:dp_id = [1,2]
# select * from depart where id in dp_id
result = User.objects.all().prefetch_related('dp')
for item in result:
print(item.name,item.dp.title)
4、代码
models
from django.db import models # Create your models here. class Depart(models.Model):
title = models.CharField(max_length=32)
number = models.CharField(max_length=32) def __str__(self):
return self.title class User(models.Model):
username = models.CharField(max_length=32)
age = models.IntegerField()
dp = models.ForeignKey(to=Depart, on_delete=models.CASCADE)
def __str__(self):
return self.username
序列化
# -*- coding: utf-8 -*-
from django.shortcuts import render # Create your views here.
from rest_framework.views import APIView
from rest_framework.serializers import ModelSerializer
from rest_framework.response import Response from app01.models import User, Depart class UserSerializer(ModelSerializer):
class Meta:
model = User # model表
# fields = '__all__' # 所有字段
fields = ['id', 'username'] class DepartSerializer(ModelSerializer):
class Meta:
model = Depart
fields = '__all__'
ORM高阶补充:only, defer,select_related的更多相关文章
- python基础编程: 编码补充、文件操作、集合、函数参数、函数递归、二分查找、匿名函数与高阶函数
目录: 编码的补充 文件操作 集合 函数的参数 函数的递归 匿名函数与高阶函数 二分查找示例 一.编码的补充: 在python程序中,首行一般为:#-*- coding:utf-8 -*-,就是告诉p ...
- 用一个简单的例子来理解python高阶函数
============================ 用一个简单的例子来理解python高阶函数 ============================ 最近在用mailx发送邮件, 写法大致如 ...
- Mapper映射语句高阶应用——ResultMap
resultMap 元素是MyBatis 中最重要最强大的元素.它就是让你远离 90%的需要从结果 集中取出数据的 JDBC代码的那个东西, 而且在一些情形下允许你做一些 JDBC 不支持的事 情. ...
- Java高阶语法---static
背景:听说static Java高阶语法是挺进BAT必经之路. static: 静态static,很多时候会令我望文生义,但是get到了static最重要的一点,其他的理解都还ok. static最重 ...
- 老师博客copy -高阶函数2
新闻 管理 Py西游攻关之函数 一 函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法.在B ...
- day20 Python 高阶函数,函数,嵌套,闭包 装饰器
高阶函数定义 1.函数接收的参数是一个函数名 2.函数的返回值是一个函数名 3.满足上述条件任意一个都可以称之为高阶函数 一.函数的接收参数是一个函数名 import time def foo(): ...
- Python高阶函数--map
map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把list 的每个元素依次作用在函数 f 上,得到一个新的 list 并返回. 例如,对于lis ...
- python 验证码 高阶验证
python 验证码 高阶验证 标签: 验证码python 2016-08-19 15:07 1267人阅读 评论(1) 收藏 举报 分类: 其他(33) 目录(?)[+] 字符型图片验证 ...
- day37-1 面向对象高阶
目录 面向对象高阶 isinstance issubclass 反射(自省) 模块的使用 放在类的使用 call 面向对象高阶 isinstance 判断是否为实例化对象,以后可以用来取代type 和 ...
随机推荐
- Pycharm 误删文件夹
在Linux下操作时误删除了Pycharm项目中的文件夹,打开垃圾桶,居然找不到,立马上网查Linux下怎么恢复文件, 冷静一下,不是还有个Ctrl + Z吗,对着Pycharm 文件浏览器 按一下, ...
- 洛谷 P2746 [USACO5.3]校园网Network of Schools
题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”).注意即使 B 在 A 学校的分发列表中, A 也不一定在 B 学校的列表中. 你要写 ...
- python 安装virtualenv和wxPython
有人说 Virtualenv.Fabric 和 PIP 是 Pythoneer 的三大神器 上一节说过了怎么安装PIP,下面继续安装virtualenv 安装wxPython时比较简单 sudo pi ...
- 怎样理解 display:none 和 visibility:hidden
1. display: none会使元素节点 "消失" , 就像 死亡后灰飞烟灭了. 它是不占位置的. 2. visibility: hidden会使元素节点 "隐藏&q ...
- 怎样创建一个独立于当前文档的新的Document对象
使用: document.implementation. 如下所示, 新创建的Document对象可以正常使用相关属性和方法, 然后将它的根节点与当前文档的根节点做一个替换. var doc = do ...
- HTML练习二--动态加载轮播图片
接上一篇https://www.cnblogs.com/shuaimeng/p/11106655.html demo下载: https://pan.baidu.com/s/1dhvzHwTHKiguy ...
- django+mysql(1)
报错误:mysqlclient 1.3.13 or newer is required; you have 0.9.3 第一种: django降到2.1.4版本就OK了 第二种(仍使用django 2 ...
- Matlab函数kmeans
Matlab函数kmeans K-means聚类算法采用的是将N*P的矩阵X划分为K个类,使得类内对象之间的距离最大,而类之间的距离最小. 使用方法:Idx=Kmeans(X,K)[Idx,C]=Km ...
- jstl的forEach 循环
jstl的forEach循环一般有两种格式 1.当需要操作循环的下标时,或者需要固定循环的次数时: <c:forEach begin="0" end="5" ...
- 2019年C题 视觉情报信息分析
2019 年第十六届中国研究生数学建模竞赛C 题 任务1中 图三:图3 中拍照者距离地面的高度 目录: 0.试题分析: 1.构建摄像机模型 2.摄像机参数假定 3.像平面坐标计算 4.图像标定及数值测 ...