Django高效查询:values_list实战详解

Django 实战案例 讲解 values_list 的用法。

  • values_list("field", flat=True) → 获取单字段的一维列表。
  • values_list("f1", "f2") → 获取多个字段,返回元组。
  • 搭配 filter / distinct / in / 外键查询 非常高效。
  • 适合用于 导出数据二次查询,因为它比取完整对象要更轻量(不会加载所有字段和对象方法)。

1. 定义模型

假设我们有一个简单的 博客系统 ,有两个模型:AuthorArticle

python 复制代码
# blog/models.py
from django.db import models


class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField(unique=True)

    def __str__(self):
        return self.name


class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name="articles")
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

2. 插入一些测试数据

python 复制代码
# 创建作者
a1 = Author.objects.create(name="Alice", email="alice@example.com")
a2 = Author.objects.create(name="Bob", email="bob@example.com")

# 创建文章
Article.objects.create(title="Django ORM 入门", content="....", author=a1)
Article.objects.create(title="Django QuerySet 高级用法", content="....", author=a1)
Article.objects.create(title="数据库优化技巧", content="....", author=a2)

3. values_list 基本用法

3.1 获取某个字段的列表

python 复制代码
# 获取所有文章的标题列表
titles = Article.objects.values_list("title", flat=True)
print(list(titles))
# 结果: ['Django ORM 入门', 'Django QuerySet 高级用法', '数据库优化技巧']

👉 flat=True 表示返回单个字段时,结果是一个一维列表,而不是元组。


3.2 获取多个字段

python 复制代码
# 获取文章标题和作者 ID
articles = Article.objects.values_list("title", "author_id")
print(list(articles))
# 结果: [('Django ORM 入门', 1), ('Django QuerySet 高级用法', 1), ('数据库优化技巧', 2)]

👉 当有多个字段时,结果是一个元组列表


3.3 搭配 distinct 去重

python 复制代码
# 获取所有作者 ID,去重
authors = Article.objects.values_list("author_id", flat=True).distinct()
print(list(authors))
# 结果: [1, 2]

3.4 搭配 filter 使用

python 复制代码
# 获取 Alice 写的文章标题
alice_titles = Article.objects.filter(author__name="Alice").values_list("title", flat=True)
print(list(alice_titles))
# 结果: ['Django ORM 入门', 'Django QuerySet 高级用法']

3.5 用于外键关联

python 复制代码
# 获取所有文章的标题和作者名字
articles = Article.objects.values_list("title", "author__name")
print(list(articles))
# 结果: [('Django ORM 入门', 'Alice'), ('Django QuerySet 高级用法', 'Alice'), ('数据库优化技巧', 'Bob')]

👉 注意这里 author__name 直接取了外键对象的字段。


4. 实际应用场景

4.1 批量取 ID 用于二次查询

python 复制代码
# 获取 Alice 的文章 ID 列表
article_ids = Article.objects.filter(author__name="Alice").values_list("id", flat=True)

# 用这些 ID 去做其他操作,比如批量删除
Article.objects.filter(id__in=article_ids).delete()

4.2 导出数据(比直接取对象更高效)

python 复制代码
# 导出文章标题和作者邮箱,直接生成 CSV
rows = Article.objects.values_list("title", "author__email")

import csv
with open("articles.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["标题", "作者邮箱"])
    writer.writerows(rows)

👉 values_list 会直接返回元组,正好适合写入 CSV/Excel。

相关推荐
ggabb13 小时前
汉语与英语启蒙读物:两种文明基因的深层对话
sqlite
张人玉18 小时前
基于 Python 的桌面端智能识别与可视化系统——生活垃圾分类可视化大屏
python·分类·sqlite·echarts·生活
言乐618 小时前
Python实现自动拉人脚本示例
开发语言·windows·python·django·pygame
淡海水19 小时前
03-02-线性-List-T-动态数组布局-扩容与操作成本
数据结构·windows·c#·list·编译·clr·机器码
皮卡丘不断更1 天前
手机优先的 Personal Ledger:把账目、学习和复盘放到同一个入口
数据库·sqlite·fastapi·开源项目·个人效率
践行见远2 天前
django之配置文件加载
django
【赫兹威客】浩哥2 天前
【无标题】
python·spring·django·pyqt
冻柠檬飞冰走茶2 天前
《数据结构实验指导-C++语言版》 求单链表list中的元素个数,即表长
开发语言·数据结构·c++·算法·list
winfredzhang2 天前
从零构建家庭照片管理系统:Django 模块化单体实战,以及我踩到的 4 个真实坑
python·postgresql·django·sqlite·bootsrap
冻柠檬飞冰走茶2 天前
《数据结构实验指导-C++语言版》 在顺序表 list 中查找元素 x
开发语言·数据结构·c++·算法·list