Django ORM詳解

Django ORM詳解

什么是ORM瓷炮?

ORM,即Object-Relational Mapping(對象關(guān)系映射)递宅,它的作用是在關(guān)系型數(shù)據(jù)庫和業(yè)務(wù)實體對象之間作一個映射娘香,這樣,我們在具體的操作業(yè)務(wù)對象的時候办龄,就不需要再去和復(fù)雜的SQL語句打交道茅主,只需簡單的操作對象的屬性和方法。

圖解:

ORM圖解

相信學(xué)過linux運維土榴,或者做運維的小伙伴都知道诀姚,在linux系統(tǒng)中有一個叫做 VFS(虛擬文件系統(tǒng))的東西,VFS 是干什么用的呢玷禽? VFS就是為不同的文件系統(tǒng)提供了一個統(tǒng)一的操作界面和應(yīng)用編程接口赫段。我個人覺得這里的ORM類似于VFS,至少處理問題的方式是類似的矢赁。

ORM中操作數(shù)據(jù)庫

本質(zhì)上來說ORM操作數(shù)據(jù)庫也不過是進行CRUD的操作糯笙。只是在ORM中將原生的SQL語句都封裝成了方法或者函數(shù),方便我們快捷調(diào)用撩银。下面來詳細介紹這些方法或函數(shù):

1)模型成員objects

Django默認(rèn)通過模型的objects對象實現(xiàn)模型數(shù)據(jù)查詢

2)數(shù)據(jù)查詢和過濾

過濾實際上就相當(dāng)于SQL語句中的where語句给涕,和過濾相關(guān)的方法或函數(shù)如下:

  • all() : 返回所有的數(shù)據(jù),得到的是一個列表

  • filter() :返回復(fù)合條件的數(shù)據(jù),條件可以有多個够庙,多個條件用 ',' 隔開恭应,得到的結(jié)果也是一個列表

  • exclude() :過濾掉符合條件的數(shù)據(jù),返回一個列表

  • order_by() : 按照指定字段進行排序

  • values() : 每條數(shù)據(jù)都作為一個字典耘眨,放在一個列表中

  • get() : 也可以接受多個條件昼榛,與 filter 不同,這里返回的是一個滿足條件的對象剔难,為單個值胆屿,且如果沒有符合條件的就會報MultiObjectReturned錯誤,而 filter 不會報錯偶宫,而是返回一個空列表非迹。

  • first():返回查詢結(jié)果中的第一個對象

  • last():返回查詢結(jié)果中的最后一個對象

  • count():返回當(dāng)前查詢結(jié)果中的對象個數(shù)

  • exists():判斷查詢結(jié)果中是否有數(shù)據(jù),如果有數(shù)據(jù)返回True纯趋,沒有返回False

  1. 限制查詢結(jié)果的條數(shù)

限制結(jié)果的條數(shù)憎兽,類似于SQL中的limit和offset。在ORM中則是使用下標(biāo)的方式去限制结闸,這里有點類似于 python 中列表的下標(biāo)運算唇兑,只是這里的下標(biāo)不能為負數(shù)酒朵。

如:模型名.objects.all()[0:5]

4)ORM中的模糊查詢

  • startswith : 匹配開始字符串

  • endswith : 匹配結(jié)束字符串

  • contains : 匹配包含該字符串的項

示例:

查詢姓王的數(shù)據(jù)
stus = Student.objects.filter(stu_name__startswith='王')
查詢以什么結(jié)束的數(shù)據(jù):
stus = Student.objects.filter(stu_name__endswith='胖')
查詢姓名中包含大的數(shù)據(jù)
stus = Student.objects.filter(stu_name__contains='大')

5)ORM中的比較運算符

  • isnull桦锄,isnotnull:是否為空。
    如:filter(stu_name__isnull=True)

  • in:是否包含在范圍內(nèi)蔫耽。這個類似python中的in
    如:filter(id__in=[1,2,3])

  • gt结耀,gte,lt匙铡,lte:大于图甜,大于等于,小于鳖眼,小于等于黑毅。
    如:filter(age__gt=10)

  • pk:代表主鍵,也就是id钦讳。

6)聚合函數(shù)

與SQL中的聚合函數(shù)一樣矿瘦,只是ORM中藥通過ggregate()函數(shù)獲得聚合函數(shù)的返回值。

  • Avg:求平均值

  • Count:求次數(shù)

  • Max:求最大值

  • Min:求最小值

  • Sum:求和

例如: Student.objects.aggregate(Max('age'))

7)F對象和Q對象

導(dǎo)入F對象和Q對象: from django.db.models import F, Q

  • F對象:使用在模型的A屬性與B屬性進行比較的時候愿卒,比如要比較一個學(xué)生的A成績和B成績的時候就需要用到F對象缚去。

例如:查找語文成績比數(shù)學(xué)成績至少高10分的學(xué)生:

stus = Student.objects.filter(stu_yuwen__gte=F('stu_shuxue') + 10)

  • Q對象:是為了將過濾條件組合起來查詢,在查詢的條件中需要組合條件 “且(&)” 或者 “或( | )” 時琼开。我們需要使用Q()查詢對象易结。

例如:查詢學(xué)生姓名不叫王大錘的,或者語文成績大于80分的學(xué)生

stus = Student.objects.filter(~Q(stu_name='王大錘') | Q(stu_yuwen__gt=80))

注意:Q()對象的前面使用字符“~”來代表意義“非”

模型字段定義

定義屬性時,需要字段類型搞动,字段類型被定義在django.db.models.fields目錄下躏精,為了方便使用,被導(dǎo)入到django.db.models中滋尉,所以在定義屬性時要導(dǎo)入庫玉控,并通過models去定義屬性。

導(dǎo)入庫:APP目錄下的models.py文件中

from django.db import models

定義屬性:

class Student(models.Model):
    stu_name = models.CharField(max_length=10)
屬性命名規(guī)則
  • 遵循標(biāo)識符規(guī)則(不使用python預(yù)定義的標(biāo)識符號狮惜,內(nèi)置函數(shù)名高诺,異常等。避免使用下劃線等)

  • 由于django的查詢方式碾篡,不允許使用連續(xù)的下劃線

字段類型
  • AutoField() : 一個根據(jù)實際ID自動增長的IntegerField虱而,通常不指定如果不指定,一個主鍵字段將自動添加到模型中.

  • CharField(max_length=字符長度,....) : 字符串开泽,默認(rèn)的表單樣式是 TextInput.

  • TextField() : 大文本字段牡拇,一般超過4000使用,默認(rèn)的表單控件是Textarea.

  • IntegerField() : 整數(shù)

  • DecimalField(max_digits=None, decimal_places=None) : 使用python的Decimal實例表示的十進制浮點數(shù), max_digits 指定總位數(shù)穆律,decimal_places 指定小數(shù)點后保留幾位惠呼。

  • FloatField() : 用Python的float實例來表示的浮點數(shù).

  • BooleanField() : true/false 字段,此字段的默認(rèn)表單控制是CheckboxInput.

  • NullBooleanField() : 支持null峦耘、true剔蹋、false三種值.

  • DateField([auto_now=False, auto_now_add=False]) : 使用Python的datetime.date實例表示的日期 auto_now 每次保存對象時,自動設(shè)置該字段為當(dāng)前時間辅髓,用于"最后一次修改"的時間戳泣崩,它總是使用當(dāng)前日期,默認(rèn)為false洛口。 auto_now_add 當(dāng)對象第一次被創(chuàng)建時自動設(shè)置當(dāng)前時間矫付,用于創(chuàng)建的時間戳,它總是使用當(dāng)前日期第焰,默認(rèn)為false.

說明:該字段默認(rèn)對應(yīng)的表單控件是一個TextInput. 在管理員站點添加了一個JavaScript寫的日歷控件买优,和一個“Today"的快捷按鈕,包含了一個額外的invalid_date錯誤消息鍵挺举。

注意:auto_now_add, auto_now, and default 這些設(shè)置是相互排斥的杀赢,他們之間的任何組合將會發(fā)生錯誤的結(jié)果。

  • TimeField() : 使用Python的datetime.time實例表示的時間豹悬,參數(shù)同DateField.

  • DateTimeField() : 使用Python的datetime.datetime實例表示的日期和時間葵陵,參數(shù)同DateField.

  • FileField() : 一個上傳文件的字段.

  • ImageField : 繼承了FileField的所有屬性和方法,但對上傳的對象進行校驗瞻佛,確保它是個有效的image.

字段選項

概述

通過字段選項脱篙,可以實現(xiàn)對字段的約束,在字段對象時通過關(guān)鍵字參數(shù)指定.

  • null : 如果為True娇钱,則該字段在數(shù)據(jù)庫中是空數(shù)據(jù),默認(rèn)值是 False

  • blank : 如果為True绊困,則該字段允許為空白文搂,默認(rèn)值是 False

注意: null 是數(shù)據(jù)庫范疇的概念,blank 是表單驗證證范疇的

  • db_column : 字段的名稱秤朗,如果未指定煤蹭,則使用屬性的名稱

  • db_index : 若值為 True, 則在表中會為此字段創(chuàng)建索引

  • default : 默認(rèn)值

  • primary_key : 若為 True, 則該字段會成為模型的主鍵字段

django會為表增加自動增長的主鍵列(ID),每個模型只能有一個主鍵列取视,如果使用選項設(shè)置某屬性為主鍵列后硝皂,則django不會再生成默認(rèn)的主鍵列。

  • unique : 如果為 True, 這個字段在表中必須有唯一值

補充

邏輯刪除

對公司來說最重要的就是數(shù)據(jù)作谭,刪除數(shù)據(jù)的操作都是不可恢復(fù)的稽物。所以在實際開發(fā)可能會對不需要的書進行刪除,這種情況我們通常都是對數(shù)據(jù)做邏輯刪除折欠,不做物理刪除贝或,防止刪除數(shù)據(jù)后,某些時候又需要該數(shù)據(jù)不能找回锐秦。那么什么是邏輯刪除呢咪奖?邏輯刪除就是在數(shù)據(jù)表中創(chuàng)建一個字段,這個字段通常是BooleanField酱床,用True表示該數(shù)據(jù)有效羊赵,用False表示該數(shù)據(jù)無效被刪除了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斤葱,一起剝皮案震驚了整個濱河市慷垮,隨后出現(xiàn)的幾起案子揖闸,更是在濱河造成了極大的恐慌揍堕,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汤纸,死亡現(xiàn)場離奇詭異衩茸,居然都是意外死亡,警方通過查閱死者的電腦和手機贮泞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門楞慈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人啃擦,你說我怎么就攤上這事囊蓝。” “怎么了令蛉?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵聚霜,是天一觀的道長狡恬。 經(jīng)常有香客問我,道長蝎宇,這世上最難降的妖魔是什么弟劲? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮姥芥,結(jié)果婚禮上兔乞,老公的妹妹穿的比我還像新娘。我一直安慰自己凉唐,他們只是感情好庸追,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著台囱,像睡著了一般锚国。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玄坦,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天血筑,我揣著相機與錄音,去河邊找鬼煎楣。 笑死豺总,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的择懂。 我是一名探鬼主播喻喳,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼困曙!你這毒婦竟也來了表伦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤慷丽,失蹤者是張志新(化名)和其女友劉穎蹦哼,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體要糊,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡纲熏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锄俄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片局劲。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖奶赠,靈堂內(nèi)的尸體忽然破棺而出鱼填,到底是詐尸還是另有隱情,我是刑警寧澤毅戈,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布苹丸,位于F島的核電站塑猖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏谈跛。R本人自食惡果不足惜羊苟,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望感憾。 院中可真熱鬧蜡励,春花似錦、人聲如沸阻桅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫂沉。三九已至稽寒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間趟章,已是汗流浹背杏糙。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蚓土,地道東北人宏侍。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像蜀漆,于是被迫代替她去往敵國和親谅河。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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