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的更多相关文章

  1. python基础编程: 编码补充、文件操作、集合、函数参数、函数递归、二分查找、匿名函数与高阶函数

    目录: 编码的补充 文件操作 集合 函数的参数 函数的递归 匿名函数与高阶函数 二分查找示例 一.编码的补充: 在python程序中,首行一般为:#-*- coding:utf-8 -*-,就是告诉p ...

  2. 用一个简单的例子来理解python高阶函数

    ============================ 用一个简单的例子来理解python高阶函数 ============================ 最近在用mailx发送邮件, 写法大致如 ...

  3. Mapper映射语句高阶应用——ResultMap

    resultMap 元素是MyBatis 中最重要最强大的元素.它就是让你远离 90%的需要从结果 集中取出数据的 JDBC代码的那个东西, 而且在一些情形下允许你做一些 JDBC 不支持的事 情. ...

  4. Java高阶语法---static

    背景:听说static Java高阶语法是挺进BAT必经之路. static: 静态static,很多时候会令我望文生义,但是get到了static最重要的一点,其他的理解都还ok. static最重 ...

  5. 老师博客copy -高阶函数2

    新闻 管理   Py西游攻关之函数   一 函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法.在B ...

  6. day20 Python 高阶函数,函数,嵌套,闭包 装饰器

    高阶函数定义 1.函数接收的参数是一个函数名 2.函数的返回值是一个函数名 3.满足上述条件任意一个都可以称之为高阶函数 一.函数的接收参数是一个函数名 import time def foo(): ...

  7. Python高阶函数--map

    map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把list 的每个元素依次作用在函数 f 上,得到一个新的 list 并返回. 例如,对于lis ...

  8. python 验证码 高阶验证

    python 验证码 高阶验证 标签: 验证码python 2016-08-19 15:07 1267人阅读 评论(1) 收藏 举报  分类: 其他(33)    目录(?)[+]   字符型图片验证 ...

  9. day37-1 面向对象高阶

    目录 面向对象高阶 isinstance issubclass 反射(自省) 模块的使用 放在类的使用 call 面向对象高阶 isinstance 判断是否为实例化对象,以后可以用来取代type 和 ...

随机推荐

  1. go 计算 MD5

    Golang的加密库都放在crypto目录下,其中MD5库在crypto/md5包中,该包主要提供了New和Sum函数 直接调用md5计算 package main import ( "cr ...

  2. Redis 学习笔记(篇八):事件

    Redis 服务器是一个事件驱动程序,服务器需要处理以下两类事件: 文件事件: Redis 服务器通过套接字与客户端(或者其他 Redis 服务器)进行连接,而文件事件就是服务器对套接字操作的抽象.服 ...

  3. 如何使用RedisTemplate访问Redis数据结构之Hash

    Redis的Hash数据机构 Redis的散列可以让用户将多个键值对存储到一个Redis键里面. public interface HashOperations<H,HK,HV> Hash ...

  4. pycharm配置git版本管理

    1.下载并安装git 首先你电脑必须安装git版本控制器(软件),在官网下载即可 2.安装git,正常安装即可 编缉器的选择,根据电脑实际情况选择合适的编缉器 安装参考:https://www.cnb ...

  5. HDU 3333-Turing Tree-线段树+离散+离线

    Description After inventing Turing Tree, 3xian always felt boring when solving problems about interv ...

  6. QT 打包exe

    QT打包主要方法: 1.把无措的代码进行Release编译 2.在运行完后,找到运行后生成的目录,以下是我的文件,名为result,运行类型有两种,一种是Debug,另一种是Release,我们需要的 ...

  7. Python 第一节随堂练习

    作业: 1 从键盘输入一个整数,判断该数字能否被2和3同时整除,能否被2整除,能否被3整除,不能被2和3整除,输出相应信息 1 my_num = int(input('请输入一个整数')) 2 if ...

  8. RBAC授权

    RBAC RBAC使用rbac.authorization.k8s.io API Group 来实现授权决策,允许管理员通过 Kubernetes API 动态配置策略,要启用RBAC,需要在 api ...

  9. JavaScript实现按照指定长度为数字前面补零输出的方法

    本文实例讲述了JavaScript实现按照指定长度为数字前面补零输出的方法.分享给大家供大家参考.具体分析如下: 例如我们希望输出的数字长度是固定的,假设为10,如果数字为123,则输出0000000 ...

  10. pthread 编程基础

    Linux系统下的多线程遵循POSIX线程接口,称为pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a.与vxworks上任务的概 ...