在 Django 中,QuerySet 是一个惰性求值的对象,它代表了从数据库中查询出来的对象集合,直接打印 QuerySet 对象本身,默认会输出类似 <QuerySet [<MyModel: object1>, <MyModel: object2>]> 这样的信息,这通常不是我们想要的。

为了以更友好、可读的方式打印 QuerySet 的内容,有几种非常实用的方法。
使用 print() 和列表推导式 (最常用)
这是最直接、最常用的方法,通过列表推导式将 QuerySet 中的每个对象转换为其字符串表示形式(通常是 __str__ 方法的返回值)。
示例:
假设你有一个 Book 模型:

# models.py
from django.db import models
class Book(models.Model):= models.CharField(max_length=200)
author = models.CharField(max_length=100)
published_date = models.DateField()
def __str__(self):
# 这个方法定义了当对象被打印或转换为字符串时的显示内容
return f"{self.title} by {self.author}"
在视图或 shell 中,你可以这样打印查询结果:
# 在 shell 或视图中 from .models import Book # 查询所有书籍 books = Book.objects.all() # 使用列表推导式打印 print([str(book) for book in books]) # 或者,如果你的 __str__ 方法已经定义好了,可以直接打印对象 # print([book for book in books])
输出结果:
['The Lord of the Rings by J.R.R. Tolkien', 'Dune by Frank Herbert', '1984 by George Orwell']
如果你想打印更详细的信息,比如所有字段:
# 打印包含所有字段的字典列表 print([book.__dict__ for book in books])
输出结果:

[
{'_state': <django.db.models.base.ModelState object at 0x...>, 'id': 1, 'title': 'The Lord of the Rings', 'author': 'J.R.R. Tolkien', 'published_date': datetime.date(1954, 7, 29)},
{'_state': <django.db.models.base.ModelState object at 0x...>, 'id': 2, 'title': 'Dune', 'author': 'Frank Herbert', 'published_date': datetime.date(1965, 8, 1)},
# ...
]
注意:_state 字段是 Django 内部使用的,你可以忽略它。
使用 print() 和 repr() (调试用)
repr() 函数会返回一个“官方的”字符串表示,目的是为了唯一地标识对象,对于模型实例,它通常会输出 ModelName(attribute='value', ...) 的格式。
from .models import Book books = Book.objects.all() print([repr(book) for book in books])
输出结果:
[<Book: The Lord of the Rings by J.R.R. Tolkien>, <Book: Dune by Frank Herbert>, <Book: 1984 by George Orwell>]
这在调试时很有用,因为它明确指出了对象的类型。
使用 django.core.serializers (序列化为 JSON/XML)
如果你需要将 QuerySet 转换为结构化的数据格式(如 JSON)以便于 API 传输或日志记录,Django 提供了强大的序列化工具。
from django.core import serializers
from .models import Book
books = Book.objects.all()
# 序列化为 JSON
json_data = serializers.serialize('json', books)
print(json_data)
# 序列化为 XML
# xml_data = serializers.serialize('xml', books)
# print(xml_data)
输出结果 (JSON):
[
{
"model": "myapp.book",
"pk": 1,
"fields": {
"title": "The Lord of the Rings",
"author": "J.R.R. Tolkien",
"published_date": "1954-07-29"
}
},
{
"model": "myapp.book",
"pk": 2,
"fields": {
"title": "Dune",
"author": "Frank Herbert",
"published_date": "1965-08-01"
}
}
]
这是处理 API 响应或数据交换时的最佳实践。
在 Django Shell 中快速查看 (print())
在 Django 的交互式 shell (python manage.py shell) 中,你可以直接 print() 一个 QuerySet,Django 会自动为你格式化输出,显示每个对象的 __str__ 表示。
python manage.py shell
>>> from myapp.models import Book >>> books = Book.objects.all() >>> print(books) <QuerySet [<Book: The Lord of the Rings by J.R.R. Tolkien>, <Book: Dune by Frank Herbert>, <Book: 1984 by George Orwell>]>
虽然输出仍然是 QuerySet 的形式,但里面的对象内容已经清晰地显示出来了,非常适合在开发调试时快速查看。
创建自定义的打印函数 (可复用)
如果你需要在多个地方打印 QuerySet,可以创建一个辅助函数来避免重复代码。
# 在 utils.py 或其他合适的地方
from django.core import serializers
def print_queryset(qs, format='str'):
"""
以指定格式打印 QuerySet。
:param qs: Django QuerySet
:param format: 'str', 'repr', 'json', 'dict'
"""
if not qs.exists():
print("QuerySet is empty.")
return
if format == 'str':
print([str(item) for item in qs])
elif format == 'repr':
print([repr(item) for item in qs])
elif format == 'json':
print(serializers.serialize('json', qs))
elif format == 'dict':
# 排除 Django 内部的 _state 字段
print([{k: v for k, v in item.__dict__.items() if k != '_state'} for item in qs])
else:
print("Unsupported format. Use 'str', 'repr', 'json', or 'dict'.")
# 使用示例
from .models import Book
from myapp.utils import print_queryset
books = Book.objects.all()
print_queryset(books, format='str')
print_queryset(books, format='json')
总结与推荐
| 场景 | 推荐方法 | 示例 |
|---|---|---|
| 日常调试/开发 | 直接 print() (在 shell 中) 或 列表推导式 print([str(o) for o in qs]) |
print(Book.objects.all()) |
| 在代码中打印可读信息 | 列表推导式 print([str(o) for o in qs]) |
print([book.title for book in books]) |
| 调试,查看对象类型 | 列表推导式 print([repr(o) for o in qs]) |
print([repr(book) for book in books]) |
| API 开发/数据交换 | django.core.serializers |
print(serializers.serialize('json', qs)) |
| 查看所有字段数据 | 列表推导式 print([o.__dict__ for o in qs]) |
print([book.__dict__ for book in books]) |
| 需要复用的打印逻辑 | 创建自定义辅助函数 | 见方法五 |
对于绝大多数情况,print([str(item) for item in your_queryset]) 是最简单、最直接、也最符合 Python 风格的解决方案。
