本文介绍 django.db.models.query.QuerySet.values
的用法。
声明
values(*fields, **expressions)
返回一个 QuerySet
,它在用作可迭代对象时返回字典,而不是模型实例。
这些字典中的每一个都代表一个对象,其键对应于模型对象的属性名称。
此示例将values()
的字典与普通模型对象进行比较:
# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
<QuerySet [<Blog: Beatles Blog>]>
# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
values()
方法采用可选的位置参数 *fields
,它指定应限制 SELECT
的字段名称。如果您指定字段,则每个字典将仅包含您指定的字段的字段键/值。如果您不指定字段,则每个字典将包含数据库表中每个字段的键和值。
例子:
>>> 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'}]>
values()
方法还采用可选的关键字参数 **expressions
,它们被传递给
:annotate()
>>> from django.db.models.functions import Lower
>>> Blog.objects.values(lower_name=Lower('name'))
<QuerySet [{'lower_name': 'beatles blog'}]>
您可以在排序中使用内置和自定义查找。例如:
>>> from django.db.models import CharField
>>> from django.db.models.functions import Lower
>>> CharField.register_lookup(Lower)
>>> Blog.objects.values('name__lower')
<QuerySet [{'name__lower': 'beatles blog'}]>
values()
子句中的聚合应用于同一 values()
子句中的其他参数之前。如果您需要按另一个值分组,请将其添加到之前的 values()
子句中。例如:
>>> from django.db.models import Count
>>> Blog.objects.values('entry__authors', entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]>
>>> Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 33}]>
一些值得一提的微妙之处:
-
如果您有一个名为
foo
的字段是ForeignKey
values()
调用将返回一个名为foo_id
的字典键,因为这是存储实际值的隐藏模型属性的名称(foo
属性是指相关模型)。当您调用values()
并传入字段名称时,您可以传入foo
或foo_id
并且您将返回相同的内容(字典键将匹配您传入的字段名称)。例如:
>>> Entry.objects.values() <QuerySet [{'blog_id': 1, 'headline': 'First Entry', ...}, ...]> >>> Entry.objects.values('blog') <QuerySet [{'blog': 1}, ...]> >>> Entry.objects.values('blog_id') <QuerySet [{'blog_id': 1}, ...]>
-
将
values()
与distinct()
distinct()
-
如果在
extra()
values()
子句,则由extra()
select
参数定义的任何字段都必须显式包含在values()
调用中。在values()
调用之后进行的任何extra()
-
组合转换和聚合需要使用两个
annotate()
values()
annotate()
>>> from django.db.models import CharField, Count >>> from django.db.models.functions import Lower >>> CharField.register_lookup(Lower) >>> Blog.objects.values('entry__authors__name__lower').annotate(entries=Count('entry')) <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]> >>> Blog.objects.values( ... entry__authors__name__lower=Lower('entry__authors__name') ... ).annotate(entries=Count('entry')) <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]> >>> Blog.objects.annotate( ... entry__authors__name__lower=Lower('entry__authors__name') ... ).values('entry__authors__name__lower').annotate(entries=Count('entry')) <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
当您知道您只需要来自少数可用字段的值并且您不需要模型实例对象的函数时,它很有用。仅选择您需要使用的字段会更有效。
最后,请注意,您可以在 values()
调用之后调用 filter()
、 order_by()
等,这意味着这两个调用是相同的:
Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()
制作 Django 的人更喜欢将所有 SQL-affecting 方法放在首位,然后(可选)任何 output-affecting 方法(例如 values()
),但这并不重要。这是你真正炫耀你的个人主义的机会。
您还可以通过 OneToOneField
、 ForeignKey
和 ManyToManyField
属性引用具有反向关系的相关模型上的字段:
>>> Blog.objects.values('name', 'entry__headline')
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
{'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>
警告
因为
属性和反向关系可以有多个相关行,包括这些行会对结果集的大小产生乘数效应。如果您在ManyToManyField
values()
查询中包含多个此类字段,这将特别明显,在这种情况下,将返回所有可能的组合。
相关用法
- Python Django QuerySet.values_list用法及代码示例
- Python Django QuerySet.select_related用法及代码示例
- Python Django QuerySet.union用法及代码示例
- Python Django QuerySet.latest用法及代码示例
- Python Django QuerySet.intersection用法及代码示例
- Python Django QuerySet.get用法及代码示例
- Python Django QuerySet.none用法及代码示例
- Python Django QuerySet.exclude用法及代码示例
- Python Django QuerySet.get_or_create用法及代码示例
- Python Django QuerySet.update_or_create用法及代码示例
- Python Django QuerySet.prefetch_related用法及代码示例
- Python Django QuerySet.first用法及代码示例
- Python Django QuerySet.annotate用法及代码示例
- Python Django QuerySet.dates用法及代码示例
- Python Django QuerySet.select_for_update用法及代码示例
- Python Django QuerySet.order_by用法及代码示例
- Python Django QuerySet.bulk_update用法及代码示例
- Python Django QuerySet.in_bulk用法及代码示例
- Python Django QuerySet.defer用法及代码示例
- Python Django QuerySet.aggregate用法及代码示例
- Python Django QuerySet.reverse用法及代码示例
- Python Django QuerySet.count用法及代码示例
- Python Django QuerySet.exists用法及代码示例
- Python Django QuerySet.explain用法及代码示例
- Python Django QuerySet.create用法及代码示例
注:本文由纯净天空筛选整理自djangoproject.com大神的英文原创作品 django.db.models.query.QuerySet.values。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。