本文介绍 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的字段是,则默认ForeignKeyvalues()调用将返回一个名为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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。
