說明:前端
本文主要深刻了解模型(models.py),涉及ORM簡介、模型定義、模型成員、模型查詢、自鏈接等。須要必定基礎,能夠先走一走基本入門流程。python
附錄一使用mysql數據庫,附錄二Django開發流程。mysql
目錄:git
1、ORM簡介sql
ORM簡介 數據庫
2、模型定義django
一、基本模型緩存
二、字段類型app
三、字段選項框架
四、關係
五、元選項
3、模型成員
一、查詢
二、Django默認的管理器
三、自定義管理器
4、模型查詢
一、查詢集
二、字段查詢
三、
5、自鏈接
附錄一:使用mysql
附錄二:Django開發流程
1、ORM簡介(引用,詳情請查閱相關文檔)
ORM(Object Relational Mapping)便是"對象-關係-映射"的簡稱,是MVC框架一個重要的部分(Django也支持ORM),它實現了數據模型與數據庫的解耦,即數據模型的設計不須要依賴於特定的數據庫,經過簡單的配置能夠輕鬆更換數據庫。
ORM的做用:
根據對象的類型生成表結構
將對象、列表的操做,轉換成sql語句
將sql查詢到的結果轉換爲對象、列表
使用ORM主要方便開發人員,極大減輕開發人員的工做量,避免手寫sql語句出現的各類問題。
Django中的模型包含存儲的字段和約束,對應着數據庫中惟一的表。
2、模型定義
一、基本的模型
1 from django.db import models 2 3 4 class BookInfo(models.Model): 5 """ 6 圖書類 => 圖書表(booktest_bookinfo) 7 """ 8 # 圖書標題 => varchar(20) 9 btitle = models.CharField(max_length=20) 10 # 發佈日期 => datetime 11 bpub_date = models.DateTimeField() 12 # 閱讀數 => int(11) 13 bread = models.IntegerField(default=0) 14 # 評論數 => int(11) 15 bcomment = models.IntegerField(default=0) 16 # 是否刪除 => tinyint 17 isDelete = models.BooleanField(default=False) 18 19 def __str__(self): 20 return self.btitle 21 22 23 class HeroInfo(models.Model): 24 """ 25 英雄類 => 英雄表(booktest_heroinfo) 26 """ 27 # 英雄名字 => varchar(20) 28 hname = models.CharField(max_length=20) 29 # 性別 => tinyint 30 hgender = models.BooleanField(default=True) 31 # 簡介 => varchar(1000) 32 hcontent = models.CharField(max_length=1000) 33 # 是否刪除 => tinyint 34 isDelete = models.BooleanField(default=False) 35 # 外鍵 => int(11) 36 hbook = models.ForeignKey(BookInfo) # 外鍵
說明:
定義屬性時,須要字段類型
字段類型被定義在django.db.models.fields目錄下,爲了方便使用,被導入到django.db.models中
使用方式:見上面代碼
對於重要數據都作邏輯刪除,不作物理刪除,實現方法是定義isDelete屬性,類型爲BooleanField,默認值爲False
二、字段類型(引用)
表單控制是指在django管理站點的前端顯示。
AutoField:根據ID自動增加的IntegerField,通常無需指定,django會自動添加到模型中,數據庫類型爲 int(11)。
BooleanFidld:true/false字段,此字段的默認表單控件是CheckboxInput,數據庫類型爲 tinyint。
NullBooleanField:支持null、true、false三種值,數據庫類型爲 tinyint。
CharField(max_length=字符長度):字符串,默認的表單控件是TextInput,數據庫類型爲 varchar(字符長度)。
TextField:大文本字段,通常字符長度超過4k使用,默認的表單控件是Textarea,數據庫類型爲 varchar(字符長度)。
IntegerField:整數,數據庫類型爲 int。
DecimalField(max_digits=None, decimal_places=None):使用python的Decimal實例表示的十進制浮點數,數據庫類型爲 decimal(P, D):
DecimalField.max_digits:位數總數
DecimalField.decimal_places:小數點後的數字位數。
FloatField:使用python的float實例來標識的浮點數。
DateField([auto_now=False, auto_noew_add=False]):使用pyhton的datetime.date實例表示日期。
參數auto_now:每次保存對象時,自動設置該字段爲當前時間,用於保存"最後一次修改"的時間戳,他老是使用當前的日期,默認爲false
參數auto_now_add:當對象第一次被建立時自動設置當前時間,用於保存建立的時間戳,它老是使用當前日期,默認爲false
該字段默認對應的表單控件是TextInput
auto_now、auto_now_add、default 這些設置是相互排斥的,他們之間任何組合將會發生錯誤的結果 。
TimeField:使用python的datetime.time實例表示的時間,參數同DatEField。
DateTimeField:使用python的datetime.datetime實例表示的日期和時間,參數同DateField
FileField:一個上傳文件的字段,通常不會把文件保存在數據庫中,建議保存文件上傳的路徑。
ImageField:繼承FieldField的全部屬性和方法,當對上傳的對象進行校驗,確保上傳是有些的image。
三、字段選項
使用:title = models.CharFidle(null=True)
null:若是爲True,Django將空值以NULL存儲到數據庫中,默認值是False。
blank:若是爲True,則該字段容許爲空,默認值是False。
null與blank對比:null是數據庫範疇的概念,blank是表單驗證範疇的。
db_column:字段的名稱,若是爲指定,則使用屬性的名稱。
db_index:若是爲True,則在表中會爲此字段建立索引
default:默認值。
primary_key:若是爲True,則該字段會成爲模型的主鍵字段。
unique:若是爲True,表示這個字段在表中必須有惟一值。
四、關係
關係的類型有以下:
ForeignKey:一對多,將字段定義在多的端中(如上面基本模型的代碼)。
ManyToManyField:多對多,將字段定義在兩端中。
OneToOneField:一對一,將字段定義在任意一端中。
訪問方式:
用一訪問多:對象.模型類小寫_set
bookinfo.heroinfo_set
用一訪問一:對象.模型類小寫
heroinfo.bookinfo
heroinfo.book_id
五、元選項
在模型類中定義類Meta,用於設置元信息
1 class BookInfo(models.Model): 2 # 元選項 3 class Meta: 4 # 數據表名 5 db_table = 'bookinfo' 6 # 對象默認排序字段,正序 7 ordering = ['id'] 8 # ordering = ['-id'] # 倒序
3、模型成員
一、查詢數據
book_list = BookInfo.objects.all()
二、Django默認的管理器
objects:是Manager類型的對象,用於與數據庫進行交互。
當定義模型時沒有指定管理器,則Django會爲模型類提供一個名爲objects的管理器。
支持明確指定管理器(若是本身指定manager,django再也不爲模型類生成名爲objects的默認管理器):
1 class BookInfo(models.Model): 2 manager1 = models.Manager()
三、自定義管理器
管理器是Django的模型進行數據庫的查詢操做的接口,Django應用的每一個模型都擁有至少一個管理器。
自定義管理器主要用於如下兩種狀況:
狀況一:修改管理器返回的原始查詢集:重寫get_query_set()方法。
狀況二:向管理器中添加額外的方法
代碼以下(manager2就是自定義的管理器):
1 class BookInfoManager(models.Manager): 2 """
3 自定義管理器 4 """
5 # 狀況一:更改默認查詢結果,只查未刪除的數據
6 def get_queryset(self): 7 return super(BookInfoManager, self).get_queryset().filter(isDelete=False) 8
9 # 狀況二:定義模型類的建立方法
10 def create(cls, btitle, bpub_date): 11 b = BookInfo() 12 b.btitle = btitle 13 b.bpub_date = bpub_date 14 b.bread = 0 15 b.bcomment = 0 16 b.isDelete = False 17 return b 18
19
20 class BookInfo(models.Model): 21 btitle = models.CharField(max_length=20) 22 bpub_date = models.DateTimeField() 23 bread = models.IntegerField(default=0) 24 bcomment = models.IntegerField(default=0) 25 isDelete = models.BooleanField(default=False) 26
27 def __str__(self): 28 return self.btitle 29
30 # 管理器
31 manager1 = models.Manager() 32 manager2 = BookInfoManager()
狀況一的測試結果以下:
狀況二的測試結果以下(簡化建立對象的過程:new->賦值->save):
4、模型查詢
一、查詢集
在管理器上調用過濾器方法返回查詢集。
查詢集通過過濾篩選後返回信的查詢集,所以能夠寫成鏈式過濾。
惰性執行:建立查詢集不會帶來任何數據的訪問,直到調用數據的時候(迭代、序列號、與if合用),纔會訪問數據庫。
返回查詢集的方法,稱爲過濾器:all()、filter()、exclude()、order_by()、values()
寫法:manager.filter(鍵1=值1, 鍵2=值2) => manager.filter(鍵1=值1).filter(鍵2=值2)
返回單個值的方法:
get():返回單個知足添加的對象
若是未找到會引起"模型類 DoesNotExist"異常
若是多條被返回,會引起"模型類 MultipleObjectsReturn"異常
count():返回當前查詢的總條數
first():返回第一個對象
last():返回最後一個對象
exists():判斷查詢集中是否有數據,有則返回True
限制查詢集:
查詢集返回列表,可使用下標的方式進行限制,等同於sql中limit和offset子句
注意:不支持負數索引
若是下標返回一個新的查詢集,不會馬上執行查詢
若是獲取一個對象,直接使用[0],等同於[0:1].get()。可是若是沒有數據,[0]引起IndexError異常,[0:1].get()引起DoesNotExist異常。
查詢集的緩存
每一個查詢集都包含一個緩存來最小化對數據庫的訪問。
在新建的查詢集中,緩存爲空,首次對查詢集求值時,會發生數據庫查詢,Django會將查詢的結果存在查詢集的緩存中,並返回請求的結果,接下來對查詢集求值將重用緩存的結果。
狀況一:構建兩個查詢集,沒法重用緩存,每次查詢都會與數據庫進行交互,增長數據庫的負載
狀況二:兩次循環使用同一個查詢集,第二次使用緩存中的數據
什麼時候查詢集不會被緩存:當只對查詢集的部分進行求值時,會檢查緩存,可是若是這部分再也不緩存中,那麼接下來查詢返回的概率將不會被緩存,這意味着使用索引來限制查詢集將不會填充緩存,若是這部分數據已經被緩存,則直接使用緩存中的數據。
1 query = BookInfo.objects.all() 2 for each in query # 緩存
3 for each in query[0,10] # 不緩存
4 # 使用子集不緩存
二、字段查詢:比較運算符,F對象,Q對象
實現where子句,做爲方法filter()、exclude()、get()的參數。
語法:屬性名__比較運算符=值,__ 表示兩個下劃線,左側是屬性名稱,右側是比較類型。
對於外鍵:使用 "屬性名__id" 表示外鍵原始值
轉義:like語句中使用%與_,匹配數據中的%與_,在過濾器中直接寫:
filter(title__contains="%") => WHERE `title` LIKE '%\%%'
比較運算符
exact:表示判等,大小寫敏感,若是沒有寫 「比較運算符」,表示判等:
filter(isDelete=False) => WHERE `isDelete` = 0
contains:是否包含。大小寫敏感:
exclude(btitle__contains='傳') => WHERE `btitle` LIKE '%傳%'
startswhit、endswith:以value開頭或結尾,大小寫敏感:
exclude(btitle__endswith='傳') => WHERE `btitle` LIKE '%傳'
exclude(btitle__startswith='傳') => WHERE `btitle` LIKE '傳%'
isnull、isnotnull:是否爲null:
filter(btitle__isnull=False) => WHERE `btitle` != null
在前面加 i 表示不區分大小寫,如:iexact、icontains、istartswith、iendswith
in:是否包含在範圍內:
filter(pk__in=[1,2,3]) => WHERE `id` IN (1, 2, 3)
gt、gte、lt、lte:大於、大於等於、小於、小於等於
filter(id__gt=3) => WHERE `id` > 3
filter(id__lte=5) => WHERE `id` <= 5
year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算:
filter(bpub_date__year=1980)
filter(bpub_date__gt=date(1980, 12, 31))
跨關係的查詢:處理join查詢:
filter(heroinfo__hcontent__contains='八') => SELECT * FROM `bookinfo` JOIN `heroinfo` ON `bookinfo`.`id`=`heroinfo`.`hbook` WHERE `heroinfo`.`hcontent` LIKE '%八%'
聚合函數:
使用aggregate()函數返回聚合函數的值
函數:Avg、Count、Max、Min、Sum
from django.db.models import Max maxDate = BookInfo.objects.aggregate(Max('bpub_date'))
count的通常用法:count = list.count()
F對象:構建等號右側字段:
可使用模型的字段A與字段B進行比較,若是A在等號左側,則B出如今等號的右側時須要經過F對象構造:
list.filter(bread__gt=F('bcomment')) => WHERE `bread` > `bcomment`
Django支持對F對象使用算數運算:
list.filter(bread__gte=F('bcomment')) => WHERE `bread` >= `bcomment` * 3
F()對象還能夠寫做「模型類__列名」進行關聯查詢:
list.filter(isDelete=F('heroinfo__isDelete')) => WHERE `bookinfo`.`isDelete` = `heroinfo`.`isDelete`
對於date/time字段,可與timedelta()進行運算:
list.filter(bpub_date__lt=F('bpub_date') + timedelta(days=1))
Q對象:處理邏輯或:
過濾器方法中關鍵字參數查詢,會合併爲And進行查詢。
須要進行or查詢,使用Q對象
Q對象(django.db.models.Q)用於封裝一組關鍵字參數,這些關鍵字參數與「比較運算符」中的相同
from django.db.models import Q list.filter(Q(pk__lt=6))
Q對象可使用&(and)、|(or)操做符組合起來
當操做符應用在兩個Q對象時,會產生一個新的Q對象
list.filter(pk__lt=6).filter(bcomment__gt=10) # WHERE `id` < 6 AND `bcomment` > 10 list.filter(Q(pk__lt=6) | Q(bcomment__gt=10)) # WHERE `id` < 6 OR `bcomment` > 10
使用~(not)操做符在Q對象前表示取反
list.filter(~Q(pk__lt=6))
可使用&|~結合括號進行分組,構造複雜的Q對象
過濾函數能夠傳遞一個或多個Q對象做爲位置參數,若是有多個Q對象,這些參數的邏輯爲and
過濾器函數能夠混合使用Q對象和關鍵字參數,全部參數都將And在一塊兒,Q對象必須位於關鍵字參數的前面。
5、自鏈接
自鏈接主要應用於無限級分類等。
1 class AreaInfo(models.Model): 2 atitle = models.CharFields(max_lenth=20) 3 aParent = mdoels.ForeignKey('self', null=True, blank=True)
訪問關聯對象:
上級:area.aParent
下級:area.areainfo_set.all()
附錄一:使用mysql數據庫
一、安裝插件:python-mysql 或 mysqlclient
個人電腦安裝的是python3.5,經過wheel安裝mysqlclient,下載地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
二、修改配置文件
附錄二:Django開發流程
一、建立項目:執行指令:django-admin startproject [項目名]
二、進入項目目錄,建立應用:執行指令:python manager.py startapp [應用名]
三、進入應用目錄,在models.py中定義模型類,要求繼承自models.Model
四、把應用加入settings.py文件中的installed_app項中
五、生成遷移文件,執行指令:python manager.py makemigrations
六、執行遷移生成表,執行指令:python manager.py migrate
七、使用模型類進行crud操做
*、使用數據庫生成模型類
python manager.py inspectdb > booktest/models.py