9势篡、Django_ORM_數(shù)據(jù)的創(chuàng)建以及增刪改查

一、查詢集QuerySet

  • 什么是查詢集耳幢?
    查詢集:從數(shù)據(jù)庫查詢得到的模型對象集合QuerySet岸晦,是一個列表
  • 什么是過濾器?
    過濾器:基于查詢集得到的結(jié)果上進(jìn)一步進(jìn)行條件篩選過濾結(jié)果

二睛藻、過濾器

返回list/多個結(jié)果的過濾器
  • values = model名稱.objects.all():返回所有數(shù)據(jù)启上;返回查詢集QuerySet對象。因?yàn)槭橇斜淼暧。云浣Y(jié)果可以使用values[索引].字段名獲取數(shù)據(jù)冈在。注意不支持負(fù)索引
  • model名稱.objects.retrieve():獲取數(shù)據(jù)表中的所有記錄,也就是返回查詢集QuerySet對象
  • model名稱.objects.filter():返回滿足條件的數(shù)據(jù)
  • model名稱.objects.exclude():返回滿足條件之外的數(shù)據(jù)
  • model名稱.objects.order_by():返回排序后的結(jié)果
返回一個對象的過濾器
  • model名稱.objects.get():返回一個model類按摘,而不是str
    1.如果查詢不到對應(yīng)的結(jié)果包券, 則會拋出模型類.DoesNotExist異常
    2.如果返回多條結(jié)果,則會拋出模型類.MultipleObjectsReturned異常
  • model名稱.objects.count():返回滿足查詢結(jié)果的總條數(shù)
  • model名稱.objects.aggregate():返回集合
  • model名稱.objects.exists():判斷返回的查詢集中是否有數(shù)據(jù)炫贤,沒有則False溅固,有則True
    PS.
    1.過濾器往往會和查詢條件結(jié)合使用進(jìn)行查詢
    2.一般情況用 model名稱.objects,但也會指定對象兰珍,比如說polls.address.
查詢集的特點(diǎn)
  • 非立刻執(zhí)行
    1.創(chuàng)建查詢集時侍郭,并不會訪問數(shù)據(jù)庫。而是直到模板中調(diào)用到數(shù)據(jù)時,才會進(jìn)行數(shù)據(jù)庫的訪問亮元。
  • 緩存
    1.查詢集的結(jié)果會被保存下來猛计,再次查詢相同的數(shù)據(jù)時,會使用之前保存下來的結(jié)果數(shù)據(jù)
    2.每個查詢集都會有一個緩存空間來保存查詢結(jié)果數(shù)據(jù)
    3.切片和索引操作沒有緩存可用爆捞,每次都會實(shí)際去執(zhí)行sql語句
查詢集索引

當(dāng)查詢集返回的是列表時奉瘤,就可以使用下標(biāo)的方式來獲取我們想要的內(nèi)容。

def AddressAPI(request):
    # 獲取第2嵌削、3毛好、4項(xiàng)
    address_values = AddressInfo.objects.all()[1:3]
    # 構(gòu)造上下文
    context = {F'AddressInfo:{address_values}'}
    return render(request, 'address.html', context)

三、查詢集的查詢條件

  • 查詢語句:模型屬性/表字段__條件運(yùn)算符=值
    1.查詢語句由三部分組成:模型屬性/表字段+兩個下劃線__+條件運(yùn)算符苛秕,所以在定義屬性模型/表字段時肌访,不能定義包括多個下劃線的名字
    2.想要實(shí)現(xiàn)SQL中的where功能,可以使用過濾器filter()艇劫、exclude()吼驶、get()
  • 條件運(yùn)算符
    1.exact:判斷相等
address = AddressInfo.objects.filter(id__exact = 1)  # 查詢id為1的地址

2.contains:判斷包含

address = AddressInfo.objects.filter(name__contains = '廣')  # 查詢地址名稱有廣的地址

3.startswith/endswith:以什么開頭/結(jié)尾
4.isnull:是否為null

address = AddressInfo.objects.filter(pid__isnull = true)  # 查詢pid為null的地址

5.in:是否包含在范圍內(nèi)

address = AddressInfo.address.filter(id__in = [1,3])  # 查詢id為1或3的地址

6.gt、gte店煞、lt蟹演、lte:大于、大于等于顷蟀、小于酒请、小
7.exclude:條件以外的數(shù)據(jù)

address = AddressInfo.objects.filter(id__exclude = 1)   # 查詢id不為1的地址

8.year、month鸣个、day羞反、week_day、hour囤萤、minute昼窗、second:對日期時間類型的屬性進(jìn)行查詢

books = BookInfo.objects.filter(pub_time__year = 2000)  # 查詢2000年發(fā)表的書籍

9.datetime.date

from datetime import date
books = BookInfo.objects.filter(pub_time__gt = date(2000,1,1))  # 查詢2000年1月1號以后發(fā)布的書籍

10.多條件查詢:或(使用|隔開查詢條件)

BookInfo.objects.filter(id__gt = 1 | pub_time__year = 2000)  # 查詢id大于1或發(fā)布年份是2000年的數(shù)據(jù)

11.多條件查詢:與(使用,隔開查詢條件)

BookInfo.objects.filter(id__gt = 1 , pub_time__year = 2000)  # 查詢id大于1,并且發(fā)布年份是2000年的數(shù)據(jù)

12.鏈?zhǔn)讲樵儯憾鄠€filter()進(jìn)行查詢(其它過濾器也可以這樣)

BookInfo.objects.filter(id__gt = 1).filter(pub_time__year = 2000) # 在查詢id大于1的結(jié)果集上涛舍,再查詢發(fā)布年份是2000年的數(shù)據(jù)

13.獲取查詢集的第一個元素以及最后一個元素:first()澄惊、last()

BookInfo.objects.filter(id__gt = 1).first()
BookInfo.objects.filter(id__gt = 1).last()

14.排序order_by('字段/-字段')

BookInfo.objects.filter(id__gt = 1).order_by('name') # 結(jié)果按照name排序,ascall碼從小到大
BookInfo.objects.filter(id__gt = 1).order_by('-name') # 結(jié)果按照name排序富雅,ascall碼從大到小
BookInfo.objects.filter(id__gt = 1).order_by('id', 'name') # 結(jié)果先按照id排序掸驱,如果相同,則按照name排序

PS.
1.exact没佑、contains毕贼、startswith、endswith這幾個運(yùn)算符都區(qū)分大小寫图筹,如需不區(qū)分大小寫帅刀,只需要在前面加上i即可:iexact、icontains远剩、istartswitch扣溺、iendswith

四、F對象和Q對象

  • F對象用于兩個屬性進(jìn)行比較瓜晤,并且支持運(yùn)算
    1.語法:
from django.db.models import F
F("屬性名/表字段")

2.例子
2.1.查詢評論量大于閱讀量的書籍

books = BookInfo.objects.filter(commentcount__gt = F('readcount'))

2.2.查詢評論量大于閱讀量2倍的書籍

books = BookInfo.objects.filter(commentcount__gt = F('readcount' * 2))
  • Q對象類似sql語句的where中的andor
    1.語法
from django.db.models import Q
# |:或
Q(屬性名/表字段1__條件運(yùn)算符=值) |  Q(屬性名/表字段2__條件運(yùn)算符=值)   # 查詢滿足第一個條件或第二個條件的數(shù)據(jù)
# ,:且
Q(屬性名/表字段1__條件運(yùn)算符=值) ,  Q(屬性名/表字段2__條件運(yùn)算符=值)  # 查詢滿足第一個條件和第二個條件的數(shù)據(jù)
# 組合
Q(屬性名/表字段1__條件運(yùn)算符=值) ,  Q(屬性名/表字段2__條件運(yùn)算符=值)  |  Q(屬性名/表字段3__條件運(yùn)算符=值)  # 查詢滿足條件1且(條件2或條件3)的數(shù)據(jù)

2.1.或:|

books = BookInfo.objects.filter(Q(readcount__gt = 10) | Q(id__lt) = 5)  # 查詢閱讀量大于10或id小于5的書籍

2.2.且:,

books = BookInfo.objects.filter(Q(readcount__gt = 10) , Q(id__lt) = 5)  # 查詢閱讀量大于10且id小于5的書籍

2.3.不等于/取反:~

books = BookInfo.objects.filter(~Q(readcount__gt = 10) , Q(id__lt) = 5)  # 查詢閱讀量小于等于10且id小于5的書籍

2.4.組合

PS.如果有其它關(guān)鍵字條件锥余,Q對象需要在關(guān)鍵字條件后面

books = BookInfo.objects.filter(pub_time = 2000 , Q(id__lt) = 5)  # pub_time是關(guān)鍵字

關(guān)于Q對象更詳細(xì)看文章:https://www.cnblogs.com/huchong/p/8027962.html

五、聚合函數(shù)

  • aggregate()過濾器調(diào)用聚合函數(shù)痢掠,然后返回單個對象
  • 聚合函數(shù):Avg('屬性名/表字段')驱犹、Max('屬性名/表字段')Min('屬性名/表字段')足画、Sum('屬性名/表字段')雄驹、Count('屬性名/表字段')。使用Count('屬性名/表字段')時淹辞,一般情況下是直接調(diào)用医舆,不需要使用aggregate()函數(shù)
  • 聚合函數(shù)在django.db.models導(dǎo)入
  • 例子(注意上下文字典中,總閱讀量的key的書寫規(guī)則)
from django.db.models import Sum

def books(request):
    # 統(tǒng)計(jì)所有書籍的總閱讀量
    readcount = BookInfo.objects.aggregate(Sum('readcount'))
    # 構(gòu)造上下文
    context = {'readcount': readcount}
    return  render(request, 'Book/book.html', context)

六象缀、關(guān)聯(lián)查詢(objects前面用的是哪個class蔬将,返回的就是哪個class對象)

一對多、多對多關(guān)聯(lián)查詢(基礎(chǔ)關(guān)聯(lián))
  • 查詢方老師所教的所有課程
 # 先查詢方老師
teacher = Teacher.objects.get(nickname = '方老師')
# 再通過方老師查詢所有相關(guān)的任務(wù)信息
classInfo = teacher.classinfo_set.all()
  • 查詢python課程的老師
# 先查詢課程
class = ClassInfo.object.get(title = 'python課程')
# 再通過關(guān)聯(lián)查詢對應(yīng)的老師
teacher = class.teacher
內(nèi)連接查詢
  • 語法:外鍵字段名__從表字段名__條件關(guān)聯(lián)模型類名小寫__屬性名__運(yùn)算符=值央星,結(jié)果和sql中的inner join相同(內(nèi)連接)
  • 查詢書名為"紅樓夢"的所有人物信息(peopleInfo)
    通過書找關(guān)聯(lián)的人
# 原始內(nèi)連接sql語句:
select p.name, b.name from peopleinfo as p inner join bookinfo as b on p.book_id = b.id where b.name = "紅樓夢";

對應(yīng)語句:

peopleInfos = PeopleInfo.objects.filter(book__name='紅樓夢')
  • 查詢書籍中人物的描述包含"紅"的書籍
    通過人找關(guān)聯(lián)的書
bookInfos = BookInfo.books.filter(peopleinfo__description__contains='紅')
自關(guān)聯(lián)查詢

自關(guān)聯(lián)的表結(jié)構(gòu):對于地區(qū)信息霞怀、分類信息等數(shù)據(jù),表結(jié)構(gòu)非常類似莉给,每個表的數(shù)據(jù)量十分有限毙石,為了充分利用數(shù)據(jù)表的大量數(shù)據(jù)存儲功能,可以設(shè)計(jì)成一張表禁谦,內(nèi)部的關(guān)系字段指向本表的主鍵
說明:關(guān)系屬性使用self指向本類胁黑,要求null和blank允許為空,因?yàn)橐患墧?shù)據(jù)是沒有父級的
更多看之前的文章:http://www.reibang.com/p/08c1be3dc9b2

七州泊、LIKE語句中轉(zhuǎn)義百分符號和下劃線

在sql語句中丧蘸,%有特殊的作用,Django可以轉(zhuǎn)義%_遥皂,這樣就可以和普通字符一樣使用

xxx.objects.filter(headline__contains='%')
# 相當(dāng)于sql:
SELECT ... WHERE headline LIKE '%\%%';

八力喷、創(chuàng)建數(shù)據(jù)/生成數(shù)據(jù)表中的數(shù)據(jù)

  • 創(chuàng)建和保存對象
#### 方法1
# 1.創(chuàng)建模型類對象,此時sql還未執(zhí)行
one_value = Userinfo(username='hello', password='hi')
# 2.調(diào)用save方法演训,執(zhí)行sql語句弟孟,生成數(shù)據(jù)
one_value.save()

#### 方法2
# 執(zhí)行sql語句,生成數(shù)據(jù)样悟,返回的是模型類對象
Userinfo.objects.create(username='hi', password='hello')
  • 保存外鍵字段
    保存外鍵字段和保存普通字段一樣拂募,只不過給外鍵字段賦值的時候迅速要注意類型要正確
  • 保存多對多字段
    需要調(diào)用add()方法庭猩,而不是直接給屬性賦值,不過不需要調(diào)用save()方法
from .model.animal import Animal
from .model.cat import Cat

animal = Animal.objects.get(pk = 1)
cat1 = Cat.objects.create(named='xiaomi')  
cat2 = Cat.objects.create(named='xiaohei')

animal.cats.add(cat1, cat2)    # 保存多對多字段

八陈症、修改數(shù)據(jù)和更新數(shù)據(jù)

  • 修改數(shù)據(jù):先獲取數(shù)據(jù)蔼水,然后修改數(shù)據(jù),再保存數(shù)據(jù)(一般用于外鍵/ForeignKey的修改)
value = Animal.objects.get(id=1)
value.namede = 'haha'
value.save()
  • 更新數(shù)據(jù):update()
    1.可以批量為QuerySet中所有的對象進(jìn)行更新操作
    2.只能對普通字段和ForeignKey字段使用
    3.對ForeignKey字段使用時录肯,需要設(shè)置新值為想要指向的新模型實(shí)例
# 普通字段
Animal.objects.filter(id=1).update(named = 'hahaha')
# ForeignKey字段
c = Cat.objects.get(id=2)  # 想要指向的新模型實(shí)例
Animal.objects.all().update(cat=c)
  • update()方法會直接轉(zhuǎn)換成一個sql語句趴腋,并立刻批量執(zhí)行,并且不會運(yùn)行模型的save()方法论咏。如果想要保存QuerySet中的每個條目并確保每個實(shí)例的save()方法都被調(diào)用优炬,你不需要使用任何特殊的函數(shù)來處理。只需要迭代它們并調(diào)用save()方法:
for item in my_queryset:
    item.save()
  • update方法可以配合F表達(dá)式厅贪。這對于批量更新同一模型中某個字段特別有用蠢护。例如增加Blog中每個Entry的pingback個數(shù):
    Entry.objects.all().update(n_pingbacks=F('n_pingbacks') + 1)。然而养涮,與filterexclude子句中的F()對象不同糊余,在update中不可以使用F()對象進(jìn)行跨表操作,只可以引用正在更新的模型的字段单寂。如果嘗試使用F()對象引入另外一張表的字段贬芥,將拋出FieldError異常:
# THIS WILL RAISE A FieldError
>>> Entry.objects.update(headline=F('blog__name'))

九、刪除數(shù)據(jù)

先獲取數(shù)據(jù)宣决,再刪除數(shù)據(jù)

value = Animal.objects.get(id=1)
value.delete() # 該方法將返回被刪除對象的總數(shù)量和一個字典蘸劈,字典包含了每種被刪除對象的類型和該類型的數(shù)量
# 支持批量刪除
Animal.objects.filter(named='haha').delete()
  • 注意
    delete()是唯一沒有在管理器上暴露出來的方法。這是刻意設(shè)計(jì)的一個安全機(jī)制尊沸,用來防止意外地請求類似Animal.objects.delete()的動作威沫,導(dǎo)致不慎刪除了所有的對象數(shù)據(jù)。如果你確實(shí)想刪除所有的對象洼专,你必須明確地請求一個完全的查詢集棒掠,如:
Animal.objecets.all().delete()

PS.本文參考:
https://blog.csdn.net/kan2016/article/details/82868636/https://www.cnblogs.com/huchong/p/8027962.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屁商,一起剝皮案震驚了整個濱河市烟很,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜡镶,老刑警劉巖雾袱,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異官还,居然都是意外死亡芹橡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門望伦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來林说,“玉大人煎殷,你說我怎么就攤上這事⊥嚷幔” “怎么了蝌数?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長度秘。 經(jīng)常有香客問我,道長饵撑,這世上最難降的妖魔是什么剑梳? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮滑潘,結(jié)果婚禮上垢乙,老公的妹妹穿的比我還像新娘。我一直安慰自己语卤,他們只是感情好追逮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粹舵,像睡著了一般钮孵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上眼滤,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天巴席,我揣著相機(jī)與錄音,去河邊找鬼诅需。 笑死漾唉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的堰塌。 我是一名探鬼主播赵刑,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼场刑!你這毒婦竟也來了般此?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤牵现,失蹤者是張志新(化名)和其女友劉穎恤煞,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體施籍,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡居扒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了丑慎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喜喂。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓤摧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出玉吁,到底是詐尸還是另有隱情照弥,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布进副,位于F島的核電站这揣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏影斑。R本人自食惡果不足惜给赞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望矫户。 院中可真熱鬧片迅,春花似錦、人聲如沸皆辽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驱闷。三九已至耻台,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間空另,已是汗流浹背粘我。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痹换,地道東北人征字。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像娇豫,于是被迫代替她去往敵國和親匙姜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容