本文介紹 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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。
