python - Django:了解 .values() 和 .values_list() 用例

标签 python python-3.x django django-models django-orm

我无法理解在什么情况下 .values() 或 .values_list() 比仅使用模型实例更好?

我认为以下都是等价的:

results = SomeModel.objects.all()
for result in results:
    print(result.some_field)

results = SomeModel.objects.all().values()
for result in results:
    print(result['some_field'])

results = SomeModel.objects.all().values_list()
for some_field, another_field in results:
    print(some_field)

显然这些都是愚蠢的例子,谁能指出使用 .values()/.values_list() 而不是直接使用 Model 实例的充分理由?

编辑:

我做了一些简单的分析,使用了一个包含 2 个 CharField(max_length=100) 的 noddy 模型 迭代仅 500 个实例以将“第一个”复制到另一个变量,取 200 次运行的平均值我得到以下结果:

 Test.objects.all()                                  time: 0.010061947107315063
 Test.objects.all().values('first')                  time: 0.00578328013420105
 Test.objects.all().values_list('first')             time: 0.005257354974746704
 Test.objects.all().values_list('first', flat=True)  time: 0.0052023959159851075
 Test.objects.all().only('first')                    time: 0.011166254281997681

所以答案很明确:性能! (大多数情况下,请参阅下面的 knbk 答案)

最佳答案

.values().values_list() 转换为 GROUP BY 查询。这意味着具有重复值的行将被分组为一个值。假设你有一个模型 People 以下数据:

+----+---------+-----+
| id |  name   | age |
+----+---------+-----+
|  1 | Alice   |  23 |
|  2 | Bob     |  42 |
|  3 | Bob     |  23 |
|  4 | Charlie |  30 |
+----+---------+-----+

然后 People.objects.values_list('name', flat=True) 将返回 3 行:['Alice', 'Bob', 'Charlie'] .名称为 'Bob' 的行被分组为一个值。 People.objects.all() 将返回 4 行。

这在做注释时特别有用。你可以这样做People.objects.values_list('name', Sum('age')),它将返回以下结果:

+---------+---------+
|  name   | age_sum |
+---------+---------+
| Alice   |      23 |
| Bob     |      65 |
| Charlie |      30 |
+---------+---------+

如您所见,两个 Bob 的年龄已相加,并在一行中返回。这与 distinct() 不同,后者仅在注释之后应用。

性能只是一个副作用,尽管它非常有用。

关于python - Django:了解 .values() 和 .values_list() 用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44280560/

相关文章:

Django-模型字段和模型属性之间有什么区别?

python - Django 如何覆盖默认表单错误消息

python - 在Python 3中动态导入模块时出现问题

python - 在 Python 3.x 中卸载模块(与重新加载不同)

django - 我应该创建表单对象还是从模型生成它们

javascript - 在 Django 中使用 ajax POST 请求

python - Pycharm 1.2 忽略名为 cvs 的目录

python - 将 PIL 与 Google Appengine SDK 结合使用时出现问题

python - 为什么 Python sys.version_info 缺少 _asdict() 方法来转换为字典?

python - 返回给定矩阵中出现次数最多的元素