當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Python Django QuerySet.values用法及代碼示例


本文介紹 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() 並傳入字段名稱時,您可以傳入 foofoo_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() 調用都將忽略其額外的選定字段。

  • values() 之後調用 only() defer() 沒有意義,因此這樣做會引發 TypeError

  • 組合轉換和聚合需要使用兩個 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() ),但這並不重要。這是你真正炫耀你的個人主義的機會。

您還可以通過 OneToOneFieldForeignKeyManyToManyField 屬性引用具有反向關係的相關模型上的字段:

>>> Blog.objects.values('name', 'entry__headline')
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
     {'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>

警告

因為 ManyToManyField 屬性和反向關係可以有多個相關行,包括這些行會對結果集的大小產生乘數效應。如果您在values() 查詢中包含多個此類字段,這將特別明顯,在這種情況下,將返回所有可能的組合。

相關用法


注:本文由純淨天空篩選整理自djangoproject.com大神的英文原創作品 django.db.models.query.QuerySet.values。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。