Django:理解.values()和.values_list()用例

时间:2017-05-31 09:15:19

标签: django django-orm

我在理解.values()或.values_list()在什么情况下比仅仅使用Model实例更难理解?

我认为以下几点都是等效的:

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个实例将'first'复制到另一个变量,平均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答案)

2 个答案:

答案 0 :(得分:2)

.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()不同,{ data: [ { id: 28, type: "blabla", name: "myname", language: "en", active: true }, { id: 5, type: "blabla", name: "myname2", language: "fr", active: false }, // etc ] } 仅适用于注释之后。

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

答案 1 :(得分:1)

values()和values_list()都是针对特定用例的优化:检索数据子集而无需创建模型实例的开销。 Django Documentation中给出了很好的解释。