Django ORM詳解
什么是ORM瓷炮?
ORM,即Object-Relational Mapping(對象關(guān)系映射)递宅,它的作用是在關(guān)系型數(shù)據(jù)庫和業(yè)務(wù)實體對象之間作一個映射娘香,這樣,我們在具體的操作業(yè)務(wù)對象的時候办龄,就不需要再去和復(fù)雜的SQL語句打交道茅主,只需簡單的操作對象的屬性和方法。
圖解:
相信學(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
- 限制查詢結(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ù)無效被刪除了。