我在理解.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答案)
答案 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中给出了很好的解释。