背景


使用Django查询需要查询数据库某一列的所有值,通过查阅官方文档发现values()values_list()是符合我要求的。

values()


返回一个 QuerySet,它返回的是字典。其中每一个字典都代表一个对象,键与模型对象的属性名相对应。

values() 方法接受可选的位置参数 *fields,它指定了 SELECT 应该被限制的字段名。如果你指定了字段,每个字典将只包含你指定字段的字段键/值。如果不指定字段,每个字典将包含数据库表中每个字段的键和值。

1
2
3
4
>>> Blog.objects.values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>

方式一获取到的是一个QuerySet,内容是键值对构成的,键为表的列名,值为对应的每个值。

通过这种方式可以获取到某一列的键值对,但是我只想要值,不要键名。

values_list()


与 values() 类似,只是在迭代时不返回字典,而是返回元组。每一个元组都包含了传入 values_list() 调用的各个字段或表达式的值——所以第一项是第一个字段,等等。例如:

1
2
3
4
5
>>> Entry.objects.values_list('id', 'headline')
<QuerySet [(1, 'First entry'), ...]>
>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list('id', Lower('headline'))
<QuerySet [(1, 'first entry'), ...]>

方式二获取到的也是一个QuerySet,但是内容是元祖形式的查询列的值。

但是我们想要的是这一列的值呀,这怎么是一个QuerySet,而且还包含了列名,或者是被包含在了元祖中?

通过传入 flat 参数为True,则返回的结果是单个值,而不是一个元组。一个例子应该可以更清楚地说明两者的区别:

1
2
3
4
5
>>> Entry.objects.values_list('id').order_by('id')
<QuerySet[(1,), (2,), (3,), ...]>

>>> Entry.objects.values_list('id', flat=True).order_by('id')
<QuerySet [1, 2, 3, ...]>

当有多个字段时,不允许传入 flat。

以一个实际代码片段举例:

1
2
# 加参数flat=True可以获取值列表,而不是一个个元祖,最终结果为:['test', 'test1', 'test2'...]
csrf_list = list(set(Csrf.objects.values_list("csrf_name", flat=True)))