0. 本文借助django-debug-toolbar来展现效果
1. 介绍
2. 使用
表
from django.db import models
class UserInfo(models.Model):
username = models.CharField(verbose_name='用户名', max_length=225)
def __str__(self):
return self.username
class Tag(models.Model):
name = models.CharField(verbose_name='标签名称', max_length=225)
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(verbose_name='标题', max_length=225)
content = models.CharField(verbose_name='内容', max_length=225)
# 外键
username = models.ForeignKey(verbose_name='用户', to='UserInfo', on_delete=models.DO_NOTHING)
tag = models.ManyToManyField(verbose_name='标签', to='Tag')
def __str__(self):
return self.title
2.1 原生的查询
2.1.1 代码
def article_list(request):
if request.method == 'GET':
# select_related---->queryset
article_queryset = models.Article.objects.all()
return render(request, 't2.html', context={'article_queryset': article_queryset})
2.1.2 图示
2.1.3 查询解释
2.2 使用select_related
2.2.2 代码
from django.shortcuts import render
from blog import models
def article_list(request):
if request.method == 'GET':
# select_related---->queryset
article_queryset = models.Article.objects.all().select_related('tag', 'username')
return render(request, 't2.html', context={'article_queryset': article_queryset})
2.2.3 图示
2.2.4 解释
2.2.5 其他常用用法
# 获取id=1的文章对象同时,获取其相关username信息
Article.objects.select_related('username').get(id=1)
# 获取id=1的文章对象同时,获取其相关作者名字信息
Article.objects.select_related('username__username').get(id=1)
# 获取id=1的文章对象同时,获取其相关tag和相关作者名字信息。下面方法等同。
# 方式一:
Article.objects.select_related('tag', 'username__username').get(id=1)
# 方式二:
Article.objects.select_related('tag').select_related('username__username').get(id=1)
# 使用select_related()可返回所有相关主键信息。all()非必需。
Article.objects.all().select_related()
# 获取Article信息同时获取username信息。filter方法和selected_related方法顺序不重要。
# 方式一:
Article.objects.filter(tag__gt=3).select_related('username')
# 方式二:
Article.objects.select_related('username').filter(tag__gt=3)
2.3. 使用prefetch_related方法
2.3.1 常用的案例
articles = Article.objects.all().select_related('category').prefecth_related('tags')
# 文章列表及每篇文章的tags对象名字信息
Article.objects.all().prefetch_related('tags__name')
# 获取id=13的文章对象同时,获取其相关tags信息
Article.objects.prefetch_related('tags').get(id=13)
# 获取文章列表及每篇文章相关的名字以P开头的tags对象信息
Article.objects.all().prefetch_related(
Prefetch('tags', queryset=Tag.objects.filter(name__startswith="P"))
)
# 文章列表及每篇文章的名字以P开头的tags对象信息, 放在article_p_tag列表
Article.objects.all().prefetch_related(
Prefetch('tags', queryset=Tag.objects.filter(name__startswith="P")),
to_attr='article_p_tag'
)
本文参考
Django基础(29): select_related和prefetch_related的用法与区别 (qq.com)
https://cn.bing.com/ck/a?!&&p=e0abbfe758bda72aJmltdHM9MTY2MjI0OTYwMCZpZ3VpZD0wZDM2NTliMy1hZDc5LTYwY2YtMDk4Mi00YmI2YWM1NzYxNmMmaW5zaWQ9NTEzNA&ptn=7&hsh=3&fclid=0d3659b3-ad79-60cf-0982-4bb6ac57616c&u=a1aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vY2NvcnovcC82MDk3MTcxLmh0bWw&ntb=1 https://cn.bing.com/ck/a?!&&p=f1ee206eac3dcc27JmltdHM9MTY2MjI0OTYwMCZpZ3VpZD0wZDM2NTliMy1hZDc5LTYwY2YtMDk4Mi00YmI2YWM1NzYxNmMmaW5zaWQ9NTE1Nw&ptn=7&hsh=3&fclid=0d3659b3-ad79-60cf-0982-4bb6ac57616c&u=a1aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vd2FuZ3l1ZTA5MjUvcC8xMTExODczOS5odG1s&ntb=1