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__'