Django模型中偶爾我們學(xué)到了一些基本的創(chuàng)建也查詢哟忍。這里專門來講一下數(shù)據(jù)庫接口相關(guān)的接口(QuerySet API)
從數(shù)據(jù)庫中查詢出來的結(jié)果一般是一個(gè)集合尚骄,這個(gè)集合叫做QuerySet文中的例子大部分是基于這個(gè)blog/models.py
from django.db import models
# Create your models here.
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.IntegerField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=50)
email = models.TextField()
def __str__(self):
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):
return self.headline
1姜骡、QuerySet 創(chuàng)建對(duì)象的方法
In [2]: from people.models import *
In [3]: b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
In [4]: b.save()
總之寂殉,一共有四種方法
方法一:
In [5]: Author.objects.create(name='liu', email='123@163.com')
Out[5]: <Author: liu>
方法二:
In [6]: a = Author(name='gao', email='234@163.com')
In [7]: a.save()
方法三:
In [8]: a1 = Author()
In [9]: a1.name='yang'
In [10]: a1.email='345@163.com'
In [11]: a1.save()
方法四:
In [12]: Author.objects.get_or_create(name='ya',email='456@163.com')
Out[12]: (<Author: ya>, True)
In [13]: Author.objects.get_or_create(name='ya',email='456@163.com')
Out[13]: (<Author: ya>, False)
# 首先嘗試獲取蹋盆,不存在就創(chuàng)建傀缩,可以防止重復(fù)
# 返回值(object漆魔,True/False)
備注:前三種方法返回的都是對(duì)應(yīng)的object坷檩,最后一種方法返回的是一個(gè)元組却音,(object,True/False)矢炼,創(chuàng)建時(shí)返回True系瓢,已存在時(shí)返回False
當(dāng)有一對(duì)多、多對(duì)一句灌、或者多對(duì)多的關(guān)系的時(shí)候夷陋,先把相關(guān)的對(duì)象查詢出來
In [27]:entry = Entry.objects.get(id=1)
In [28]: cheese_blog = Blog.objects.get(name='Beatles Blog')
In [29]: entry.blog = cheese_blog
In [30]: entry.save()
2、獲取對(duì)象的方法
In [34]: Author.objects.all() # 查詢所有
Out[34]: <QuerySet [<Author: liu>, <Author: gao>, <Author: yang>, <Author: ya>]>
In [35]: Author.objects.all()[:4]
Out[35]: <QuerySet [<Author: liu>, <Author: gao>, <Author: yang>, <Author: ya>]> # 切片操作胰锌,獲取4個(gè)人骗绕,不支持負(fù)索引,切片可以節(jié)約內(nèi)存资昧,不支持負(fù)索引酬土,后面有相應(yīng)解決辦法,第7條
In [36]: Author.objects.get(name='liu')
Out[36]: <Author: liu> # 名稱為 WeizhongTu 的一條格带,多條會(huì)報(bào)錯(cuò)
#get是用來獲取一個(gè)對(duì)象的撤缴,如果需要獲取滿足條件的一些人,就要用到filter
In [37]: Author.objects.filter(name='liu')
Out[37]: <QuerySet [<Author: liu>]> # 等于
In [38]: Author.objects.filter(name__exact='liu')
Out[38]: <QuerySet [<Author: liu>]> # 名稱為 abc 但是不區(qū)分大小寫践惑,可以找到 ABC, Abc, aBC腹泌,這些都符合條件
In [39]: Author.objects.filter(name__regex='^liu')
Out[39]: <QuerySet [<Author: liu>]> # 正則表達(dá)式查詢
# filter是找出滿足條件的,當(dāng)然也有排除符合某條件的
In [40]: Author.objects.exclude(name__contains='y')
Out[40]: <QuerySet [<Author: liu>, <Author: gao>]> # 排除包含 "y" 的Author對(duì)象
In [44]: Author.objects.exclude(email='345@163.com').filter(name__contains='y')
Out[44]: <QuerySet [<Author: ya>]> # 找出名稱含有"y", 但是排除email是'345@163.com'的
3尔觉、刪除符合條件的結(jié)果
和上面類似凉袱,得到滿足條件的結(jié)果,然后delete就可以(危險(xiǎn)操作侦铜,正式場(chǎng)合操作務(wù)必慎重)专甩,比如:
In [47]: Author.objects.filter(name__contains='g').delete()
Out[47]: (2, {'people.Author': 2, 'people.Entry_authors': 0}) # 刪除 名稱中包含“g”得人
In [48]: Author.objects.filter(name__contains='g').delete()
Out[48]: (0, {}) # 沒有名稱中包含”g“的人
In [49]: a = Author.objects.filter(name__contains='g')
In [50]: a.delete()
Out[50]: (0, {}) # 寫成兩條語句也是可以的,效果一樣钉稍,但是實(shí)際上Django只執(zhí)行了一條SQL語句
4涤躲、更新某個(gè)內(nèi)容
批量更新,適用于all()贡未、filter()种樱、exclude()等后面(危險(xiǎn)操作,正式場(chǎng)合操作務(wù)必慎用)
In [64]: Author.objects.filter(name__contains='l').update(name="sansa")
Out[64]: 2 # 名字中包含“l(fā)”得人都改成“sansa” 返回2,說明修改了兩條數(shù)據(jù)
In [65]: Author.objects.filter(name__contains='s')
Out[65]: <QuerySet [<Author: sansa>, <Author: sansa>]>
單個(gè)object更新俊卤,適合于.get()嫩挤,get_or_create(),update_or_create()等得到的obj,和新建很類似消恍。
In [4]: a = Author.objects.get(name="li")
In [5]: a.name="lil"
In [6]: a.email="111@111.com"
In [7]: a.save() # 最后不要忘記保存F裾选!狠怨!
5约啊、QuerySet 是可迭代的
In [20]: a = Author.objects.all()
In [21]: for e in a:
...: print(e)
...:
lil
ya
gao
yang
Author.objects.all() 或者 QuerySet 是查詢所有的Author條目邑遏。
注意事項(xiàng):
1、如果只檢查Author中是否有對(duì)象恰矩,應(yīng)該用
In [22]: Author.objects.all().exists()
Out[22]: True
2记盒、QuerySet 支持切片,可以節(jié)省內(nèi)存
In [23]: Author.objects.all()[:2]
Out[23]: <QuerySet [<Author: lil>, <Author: ya>]>
3外傅、用len(a)可以得到Author的數(shù)量孽鸡,但是推薦用:
In [24]: Author.objects.count()
Out[24]: 4
# 或者用的是SQL:select count(*)
4、list(a)可以強(qiáng)行將QuerySet變成列表
6栏豺、QuerySet是可以用pickle序列化到硬盤在讀取出來的
>>> import pickle
>>> query = pickle.loads(s) # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query # Restore the original 'query'.
7、QuerySet 查詢結(jié)果排序
作者按照名稱排序
In [27]: Author.objects.all().order_by('name')
Out[27]: <QuerySet [<Author: gao>, <Author: lil>, <Author: ya>, <Author: yang>]>
In [28]: Author.objects.all().order_by('-name')
Out[28]: <QuerySet [<Author: yang>, <Author: ya>, <Author: lil>, <Author: gao>]>
# 在column name 前面加一個(gè)負(fù)號(hào)豆胸,可以實(shí)現(xiàn)倒序
8奥洼、QuerySet 支持鏈?zhǔn)讲樵?/h6>
In [39]: Author.objects.filter(name__contains='y').filter(email="456@163.com")
Out[39]: <QuerySet [<Author: ya>]>
9、QuerySet 不支持負(fù)索引
In [56]: Author.objects.all()
Out[56]: <QuerySet [<Author: lil>, <Author: ya>, <Author: gao>, <Author: yang>]>
In [57]: Author.objects.all().reverse()
Out[57]: <QuerySet [<Author: lil>, <Author: ya>, <Author: gao>, <Author: yang>]> # 直接用reverse()并沒有起作用
In [58]: Author.objects.all().order_by('name')
Out[58]: <QuerySet [<Author: gao>, <Author: lil>, <Author: ya>, <Author: yang>]> # 按照名字排序
In [59]: Author.objects.all().order_by('name').reverse()
Out[59]: <QuerySet [<Author: yang>, <Author: ya>, <Author: lil>, <Author: gao>]> # 按照名字排序之后再逆序reverse()正常使用
10晚胡、QuerySet 重復(fù)問題灵奖,使用distinct() 去重
In [39]: Author.objects.filter(name__contains='y').filter(email="456@163.com")
Out[39]: <QuerySet [<Author: ya>]>
In [56]: Author.objects.all()
Out[56]: <QuerySet [<Author: lil>, <Author: ya>, <Author: gao>, <Author: yang>]>
In [57]: Author.objects.all().reverse()
Out[57]: <QuerySet [<Author: lil>, <Author: ya>, <Author: gao>, <Author: yang>]> # 直接用reverse()并沒有起作用
In [58]: Author.objects.all().order_by('name')
Out[58]: <QuerySet [<Author: gao>, <Author: lil>, <Author: ya>, <Author: yang>]> # 按照名字排序
In [59]: Author.objects.all().order_by('name').reverse()
Out[59]: <QuerySet [<Author: yang>, <Author: ya>, <Author: lil>, <Author: gao>]> # 按照名字排序之后再逆序reverse()正常使用
一般情況下,QuerySet 中不會(huì)出來重復(fù)問題估盘,重復(fù)是很罕見的瓷患,但是當(dāng)跨域多張表進(jìn)行檢索后,結(jié)果并到一起遣妥,可能會(huì)出來重復(fù)的值(遇到的問題)