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 和 ...
随机推荐
- vue中页面跳转拦截器的实现方法
首先对index.js的router进行配置; export default new Router({ routes: [ { path: '/consultancy', name: 'consult ...
- 【js】null 和 undefined的区别?
1.首先看一个判断题:null和undefined 是否相等 console.log(null==undefined)//true console.log(null===undefin ...
- [转载]clip gradient抑制梯度爆炸
[转载]clip gradient抑制梯度爆炸 来源:https://blog.csdn.net/u010814042/article/details/76154391 1.梯度爆炸的影响 在一个只有 ...
- 【QT 学习笔记】 一、 VS2015+ QT环境安装
1. 安装 qt-opensource-windows-x86-msvc2015_64-5.6.0.exe (根据自己的VS版本来安装) 下载地址 http://download.qt. ...
- python计算出现错误
用python计算39.8-0.1得出的结果是39.699999999999996 其他数字计算正确,唯独这个计算错误. 原因: 中文解释: https://docs.python.org/zh-cn ...
- Redis笔记一
REmote DIctionary Server 是一个开源.内存存储的数据结构服务器,可以用作数据库来存储key-value数据,支持字符串,哈希表,列表,集合,位图,地理空间信息等数据类型,同时也 ...
- 如何在调用Marketing Cloud contact创建API时增加对扩展字段的支持
需求:扩展字段"微信ID"是我创建出来的extension field,我想用Marketing Cloud提供的contact creation API,在创建contact时也 ...
- composer安装学习
Packagist 镜像 网站地址 http://www.phpcomposer.com/ 请各位使用本镜像的同学注意: 本镜像已经依照 composer 官方的数据源安全策略完全升级并支持 http ...
- CI/CD持续集成小结
一.概念 什么是devops,基于Gitlab从零开始搭建自己的持续集成流水线(Pipeline) https://blog.csdn.net/chengzi_comm/article/details ...
- DDOS 攻击的防范教程--转载自阮一峰的博客
一个多月前,我的个人网站遭受 DDOS 攻击,下线了50多个小时.这篇文章就来谈谈,如何应对这种攻击. 需要说明的是,我对 DDOS 并不精通,从没想过自己会成为攻击目标.攻击发生以后,很多素昧平生的 ...