查詢集(QuerySet)方法
本文 model 設定如下:
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
查詢集的方法
filter()
返回一個新的 QuerySet,返回與查詢條件匹配的物件。exclude()
返回一個新的 QuerySet,返回查詢條件不匹配的物件。annotate()
(待補充)
查詢集排序
預設情況下,QuerySet 根據模型 Meta 類的 ordering 選項排序。要使用特定的排序方法時可以用 order_by():
# 按 pub_date 降序排列
Entry.objects.filter(pub_date__year=2005).order_by('-pub_date')
# 按 pub_date 降序排列,再按 headline 升序排列
Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
若要隨機排序,請使用 " ? ":
Entry.objects.order_by('?')
注:order_by('?') 查詢可能耗費資源且很慢。
涉及外來鍵的排序
若要按照另外一個模型中(即:外來鍵或其他對應關係)的欄位排序,可以在欄位的名稱後面跟上兩個下劃線(__),再跟上新模型中的欄位的名稱,例如:
# 按照所屬的部落格的名稱排序
Entry.objects.order_by('blog__name')
如果單純用另一個模型的小寫名來排序,相當於是按照該模型的主鍵來排序:
# 這兩種寫法等價
Entry.objects.order_by('blog')
Entry.objects.order_by('blog__id')
反向排序
使用 reverse() 方法可以使一個排好序的查詢集反向排序
e = Entry.objects.order_by('blog_id')
# 反向排序
e.reverse()
distinct
(待補充)
values
返回一個ValuesQuerySet —— QuerySet 的一個子類,對它進行迭代操作時返回字典。
e = Entry.objects.order_by('blog')
v = e.values()
>>> type(v)
<class 'django.db.models.query.QuerySet'>
# 對它進行迭代操作時將返回一個字典
>>> type(v[0])
<class 'dict'>
values() 接收可選的位置引數 *fields,指定輸出哪些欄位:
>>> e.values('id', 'headline')
<QuerySet [{'headline': 'ringo 教你打鼓', 'id': 3}, {'headline': 'John 和 Paul
教你作曲', 'id': 4}, {'headline': 'George 教你彈吉他', 'id': 5}]>
如果 values() 的引數是一個ForeignKey,預設的 values() 呼叫返回的字典將會是一個叫做 母表的 id :
>>> Entry.objects.values('blog')
# 返回的是母表的 id
<QuerySet [{'blog': 2}, {'blog': 2}, {'blog': 2}]>
# 這種寫法與上面的等價
>>> Entry.objects.values('blog_id')
values_list
與 values() 類似,只是在迭代時返回的是元組而不是字典:
>>> e = Entry.objects.values_list('id', 'headline')
>>> type(e)
<class 'django.db.models.query.QuerySet'>
# 返回一個元組
>>> type(e[0])
<class 'tuple'>
當 flat 引數為True 時,它表示返回的結果為單個值而不是元組:
>>> e = Entry.objects.values_list('id', flat=True).order_by('id')
>>> e[0]
1
>>> type(e[0])
<class 'int'>
注意:如果有多個欄位,傳遞 flat 將發生錯誤。
如果你不傳遞任何值給 values_list(),它將返回模型中的所有欄位。
dates
dates(field, kind, order='ASC')
返回 DateQuerySet - QuerySet,其計算結果為 datetime.date 物件。
field 應為模型的 DateField 的名稱。 kind 應為 "year"、"month" 或 "day"。
- "year" 表示精確到年
- “month” 表示精確到月
- “day” 表示精確到日
order(預設為“ASC”)應為'ASC'或'DESC'。
注:asc 是升序排列,desc 是降序排列。
例子:
# 返回值精確到年,因為所有 entry 的 pub_date 都是 2017年,所以只有一個返回值
>>> Entry.objects.dates('pub_date', 'year')
<QuerySet [datetime.date(2017, 1, 1)]>
# 返回值精確到月
>>> Entry.objects.dates('pub_date', 'month')
<QuerySet [datetime.date(2017, 2, 1)]>
# 精確到日,預設為升序
>>> Entry.objects.dates('pub_date', 'day')
<QuerySet [datetime.date(2017, 2, 1), datetime.date(2017, 2, 2)]>
# 精確到日,降序排列
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
<QuerySet [datetime.date(2017, 2, 2), datetime.date(2017, 2, 1)]>
# 查詢某篇博文的 pub_date
>>> e = Entry.objects.filter(headline='George 教你彈吉他')
>>> e.dates('pub_date', 'day')
<QuerySet [datetime.date(2017, 2, 1)]>
datetimes
(待補充)
None
呼叫 none() 將建立一個從不返回任何物件的查詢集,並且在訪問結果時不會執行任何查詢。
qs.none() 查詢集是 EmptyQuerySet 的一個例項。
>>> Entry.objects.none()
[]
>>> from django.db.models.query import EmptyQuerySet
>>> isinstance(Entry.objects.none(), EmptyQuerySet)
True
all()
返回全部
select_related
返回一個QuerySet。當使用 select_related 去查詢帶外來鍵關係的物件時,它會預載入相關的資料表,以後再查詢外來鍵關係時就不用再去請求資料庫。
下面的例子解釋了普通查詢和 select_related() 查詢的區別:
- 普通查詢:
# 請求資料庫
e = Entry.objects.get(id=5)
# 再次請求資料庫
b = e.blog
- select_related 查詢:
# 請求資料庫
e = Entry.objects.select_related('blog').get(id=5)
# 無需再請求資料庫,因為相關資料已經預載入
b = e.blog
假如有“外來鍵鏈”,如下所示:
from django.db import models
class City(models.Model):
# ...
pass
class Person(models.Model):
# ...
hometown = models.ForeignKey(City)
class Book(models.Model):
# ...
author = models.ForeignKey(Person)
可以這樣呼叫將快取關聯的 Person 和關聯的 City:
b = Book.objects.select_related('author__hometown').get(id=4)
p = b.author
c = p.hometown
prefetch_related
(待補充)
參考:http://blog.jobbole.com/74881/
extra
(待補充)
不會返回 QuerySets 的方法
get(**kwargs)
create(**kwargs)
get_or_create(defaults=None, **kwargs)
update_or_create(defaults=None, **kwargs)
bulk_create(objs, batch_size=None)
bulk_create 方法是用一個列表來批量插入資料:
Entry.objects.bulk_create([
Entry(headline="Django 1.0 Released"),
Entry(headline="Django 1.1 Announced"),
Entry(headline="Breaking: Django is awesome"
)])
count()
in_bulk(id_list)
獲取主鍵值的列表,並返回一個字典:
# 如果不填引數將獲取全部
>>> Entry.objects.in_bulk()
{
3: <Entry: ringo 教你打鼓>,
4: <Entry: John 和 Paul 教你作曲>,
5: <Entry: George 教你彈吉他>
}
>>> Entry.objects.in_bulk([3])
{3: <Entry: ringo 教你打鼓>}
>>> Entry.objects.in_bulk([3,4])
{
3: <Entry: ringo 教你打鼓>,
4: <Entry: John 和 Paul 教你作曲>
}
- iterator()
iterator() 方法可以把一個查詢集變成一個迭代器:
a = Entry.objects.all()
a = a.iterator()
# 生成一個迭代器
>>> type(a)
generator
- latest(field_name=None)
按日期返回表中的最的新物件:
# 返回 pub_date 最新的物件
>>> Entry.objects.latest('pub_date')
<Entry: John 和 Paul 教你作曲>
- earliest(field_name=None)
按日期返回表中的最早的物件:
>>> Entry.objects.earliest('pub_date')
<Entry: ringo 教你打鼓>
- first()
返回結果集的第一個物件, 當沒有找到時返回None。
例:
>>> Entry.objects.first()
<Entry: ringo 教你打鼓>
- last()
類似 first(),只是返回的是查詢集中最後一個物件。
- aggregate(*args, **kwargs)
(聚合查詢,待補充)
- exists()
判斷某 QuerySet 是否存在某個物件,返回 True 或 False。這是一個高效的查詢方法,特別是 QuerySet 比較大的時候。
>>> entry = Entry.objects.get(pk=3)
>>> all_entry = Entry.objects.all()
>>> all_entry.filter(pk=entry.pk).exists()
True
>>> some_entry = Entry.objects.filter(pk=4)
>>> some_entry.filter(pk=entry.pk).exists()
False
它將比下面的方法快很多:
if entry in some_queryset:
……
若要判斷一個 QuerySet 是否包含任何元素,
if some_queryset.exists():
會快於
if some_queryset:
- update(**kwargs)
更新指定欄位,例子:
e = Entry.objects.filter(pk=4)
e.update(rating=1)
# 也可以批量修改查詢集裡面的全部欄位
e = Entry.objects.all()
e.update(rating=1)
- delete()
刪除指定欄位,例子:
# 刪除指定部落格的全部博文
b = Blog.objects.get(pk=1)
Entry.objects.filter(blog=b).delete()
# 刪除全部博空
blogs = Blog.objects.all()
blogs.delete(
- as_manager
(待補充)
相關文章
- Django 2.0 模型層中 QuerySet 查詢操作介紹Django模型
- elasticsearch查詢之大資料集分頁查詢Elasticsearch大資料
- mysql查詢語句集MySql
- 北京社保查詢方法
- 備忘:laravel 對查詢結果集可以迴圈where查詢Laravel
- Django-ORM---查詢集介紹DjangoORM
- 方法快取與查詢快取
- Django ORM QuerySetDjangoORM
- 關於mysql查詢字符集不匹配問題的解決方法MySql
- mysql查詢去重方法解析MySql
- Spring JPA 定義查詢方法Spring
- pandas 的幾個查詢方法
- Java--String類查詢方法Java
- 表膨脹的查詢方法
- Django中的QuerySetDjango
- Django(19)QuerySet APIDjangoAPI
- 谷歌收錄批次查詢,教你批次查詢谷歌收錄的方法谷歌
- Python—Django:關於在Django框架中對資料庫的查詢函式,查詢集和關聯查詢PythonDjango框架資料庫函式
- PostgreSQL函式:返回表查詢結果集SQL函式
- Mybatis 查詢語句結果集總結MyBatis
- DBeaver 匯出多個查詢結果集
- 谷歌收錄批次查詢,谷歌收錄批次查詢的方法步驟谷歌
- ABAP 查詢系統BAPI的方法API
- 理解 sole() 查詢構造器方法
- 實現 MyBatis 流式查詢的方法MyBatis
- Django常用的QuerySet操作Django
- SQL查詢的:子查詢和多表查詢SQL
- elasticsearch查詢之大資料集分頁效能分析Elasticsearch大資料
- 使用並查集處理集合的合併和查詢問題並查集
- mysql-分組查詢-子查詢-連線查詢-組合查詢MySql
- Android SQL資料庫查詢方法 query( )AndroidSQL資料庫
- ssl證書到期時間查詢方法
- SQL查詢是否”存在”的新方法SQL
- django對資料庫查詢基本方法Django資料庫
- join方法應用之—查詢航班資訊
- SQL Server 語句日期格式查詢方法SQLServer
- Linq查詢語法與擴充方法
- Python中使用MySQL模糊查詢的方法PythonMySql
- 教你幾招HASH表查詢的方法