django_filter的values / values_list

from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def __str__(self): # __unicode__ on Python 2 return self.name class Author(models.Model): name = models.CharField(max_length=50) email = models.EmailField() def __str__(self): # __unicode__ on Python 2 return self.name class Entry(models.Model): blog = models.ForeignKey(Blog) headline = models.CharField(max_length=255) body_text = models.TextField() pub_date = models.DateField() mod_date = models.DateField() authors = models.ManyToManyField(Author) n_comments = models.IntegerField() n_pingbacks = models.IntegerField() rating = models.IntegerField() def __str__(self): # __unicode__ on Python 2 return self.headline 

values

values(*fields)
返回一個ValuesQuerySet —— QuerySet 的一個子類,迭代時返回字典而不是模型實例對象。python

每一個字典表示一個對象,鍵對應於模型對象的屬性名稱。數據庫

下面的例子將values() 與普通的模型對象進行比較:django

# This list contains a Blog object. >>> Blog.objects.filter(name__startswith='Beatles') [<Blog: Beatles Blog>] # This list contains a dictionary. >>> Blog.objects.filter(name__startswith='Beatles').values() [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}] 

values() 接收可選的位置參數*fields,它指定SELECT 應該限制哪些字段。若是指定字段,每一個字典將只包含指定的字段的鍵/值。若是沒有指定字段,每一個字典將包含數據庫表中全部字段的鍵和值。ruby

例如:bash

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

值得注意的幾點:
若是你有一個字段foo 是一個ForeignKey,默認的values() 調用返回的字典將有一個叫作foo_id 的鍵,由於這是保存實際的值的那個隱藏的模型屬性的名稱(foo 屬性引用關聯的模型)。當你調用values() 並傳遞字段的名稱,傳遞foofoo_id 均可以,獲得的結果是相同的(字典的鍵會與你傳遞的字段名匹配)。app

例如:函數

>>> Entry.objects.values() [{'blog_id': 1, 'headline': 'First Entry', ...}, ...] >>> Entry.objects.values('blog') [{'blog': 1}, ...] >>> Entry.objects.values('blog_id') [{'blog_id': 1}, ...] 
  • 當values() 與distinct() 一塊兒使用時,注意排序可能影響最終的結果。詳細信息參見distinct() 中的備註。ui

  • 若是values() 子句位於extra() 調用以後,extra() 中的select 參數定義的字段必須顯式包含在values() 調用中。values() 調用後面的extra() 調用將忽略選擇的額外的字段。spa

  • 在values() 以後調用only() 和defer() 不太合理,因此將引起一個NotImplementedError。code

New in Django 1.7:
新增最後一點。之前,在values() 以後調用only() 和defer() 是容許的,可是它要麼會崩潰要麼返回錯誤的結果。

ValuesQuerySet 用於你知道你只須要字段的一小部分,而不須要用到模型實例對象的函數。只選擇用到的字段固然更高效。

最後,要注意ValuesQuerySetQuerySet 的子類,它實現了大部分相同的方法。你能夠對它調用filter()order_by() 等等。這表示下面的兩個調用徹底相同:

Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()

Django 的做者喜歡將影響SQL 的方法放在前面,而後放置影響輸出的方法(例如values()),可是實際上無所謂。這是賣弄你個性的好機會。

你能夠經過OneToOneField、ForeignKey 和 ManyToManyField 屬性反向引用關聯的模型的字段:

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

警告

由於ManyToManyField 字段和反向關聯可能有多個關聯的行,包含它們可能致使結果集的倍數放大。若是你在values() 查詢中包含多個這樣的字段將更加明顯,這種狀況下將返回全部可能的組合。

values_list

values_list(*fields, flat=False)
與values() 相似,只是在迭代時返回的是元組而不是字典。每一個元組包含傳遞給values_list() 調用的字段的值 —— 因此第一個元素爲第一個字段,以此類推。例如:

>>> Entry.objects.values_list('id', 'headline') [(1, 'First entry'), ...] 

若是隻傳遞一個字段,你還能夠傳遞flat 參數。若是爲True,它表示返回的結果爲單個值而不是元組。一個例子會讓它們的區別更加清晰:

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

若是有多個字段,傳遞flat 將發生錯誤。

若是你不傳遞任何值給values_list(),它將按照字段在模型中定義的順序, 返回模型中的全部字段。

注意,這個方法返回ValuesListQuerySet。這個類的行爲相似列表。大部分時候它足夠用了,可是若是你須要一個真實的Python 列表對象,能夠對它調用list(),這將會對查詢集求值。

例如:

School.objects.filter(school_id=1).values_list("id", "flat = true")

上述orm解釋:

查找School表中school_id爲1的id,這將返回一個id列表,而不是單個id元組列表。

差別巨大,values_list速度更快。flat = true使得它更快,由於python不須要實例化列表中的全部對象,只返回數據庫值。

爲了證實它更快,由於Django認識到咱們使用查詢集做爲查詢集的參數,所以它將它們組合到一個查詢中 - 它不會首先將查詢集計算values_list爲列表
有一點須要注意的是,列表理解中values / values_list的行爲有所不一樣:

  • values / values_list將產生存儲在該字段中的實際值,即,僅僅是id(不是整個對象)
  • 若是該值是一個外鍵,而且在模型中設置了適當的關係,則列表理解將爲您提供外鍵引用的對象
class Building(models.Model): corporation = models.ForeignKey('company.Corporation', verbose_name=u'學校', related_name='buildings') number = models.CharField(u'樓棟編號', max_length=10, unique=True, db_index=True) create_time = models.DateTimeField(u'建立時間', auto_now_add=True) 

獲取Building的number字段列表

In [1]: from apps.dormitory.models import Building In [2]: buildings = Building.objects.values('number') In [3]: buildings Out[3]: [{'number': u'1'}, {'number': u'2'}, {'number': u'3'}, {'number': u'4'}, {'number': u'5'}] In [4]: buildings_ = Building.objects.values_list('number') In [5]: buildings_ Out[5]: [(u'1',), (u'2',), (u'3',), (u'4',), (u'5',)] In [6]: buildings_list = Building.objects.values_list('number', flat=True) In [7]: buildings_list Out[7]: [u'1', u'2', u'3', u'4', u'5'] 

從以上代碼能夠看出:

values方法能夠獲取number字段的字典列表。

values_list能夠獲取number的元組列表。

values_list方法加個參數flat=True能夠獲取number的值列表。

連接:https://www.jianshu.com/p/7c7645674ae0

相關文章
相關標籤/搜索