杰瑞科技汇

如何打印Python的Queryset对象内容?

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

如何打印Python的Queryset对象内容?-图1
(图片来源网络,侵删)

为了以更友好、可读的方式打印 QuerySet 的内容,有几种非常实用的方法。

使用 print() 和列表推导式 (最常用)

这是最直接、最常用的方法,通过列表推导式将 QuerySet 中的每个对象转换为其字符串表示形式(通常是 __str__ 方法的返回值)。

示例:

假设你有一个 Book 模型:

如何打印Python的Queryset对象内容?-图2
(图片来源网络,侵删)
# 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])

输出结果:

如何打印Python的Queryset对象内容?-图3
(图片来源网络,侵删)
[
    {'_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 风格的解决方案。

分享:
扫描分享到社交APP
上一篇
下一篇