一、模型
Django對(duì)各種數(shù)據(jù)庫(kù)提供了很好的支持蘸鲸,Django為這些數(shù)據(jù)庫(kù)提供了統(tǒng)一的調(diào)用API(即不管底層操作哪種數(shù)據(jù)庫(kù),我們只管模型對(duì)象操作即可膝舅,其實(shí)就是屏蔽掉數(shù)據(jù)庫(kù)操作的差異性),這就可以根據(jù)不同的業(yè)務(wù)需求選擇不同的數(shù)據(jù)庫(kù)仍稀。
二、配置數(shù)據(jù)
- 在工程目錄下
__init__.py
文件
import pymysql
pymysql.install_as_MySQLdb()
安裝鏈接mysql的驅(qū)動(dòng): pip install pymysql
- 在工程目錄下
settings.py
文件中,修改DATABASES
使用了ORM對(duì)象關(guān)系映射耿芹,使用哪種數(shù)據(jù)庫(kù)操作都是一樣,就是在設(shè)置數(shù)據(jù)庫(kù)連接時(shí)不一樣琉闪。
# Django默認(rèn)使用SQLine數(shù)據(jù)庫(kù)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 將項(xiàng)目數(shù)據(jù)庫(kù)改為MySql
DATABASES = {
'default': {
# 修改為mysql(驅(qū)動(dòng))
'ENGINE': 'django.db.backends.mysql',
# 鏈接數(shù)據(jù)庫(kù)砸彬,并創(chuàng)建對(duì)應(yīng)的數(shù)據(jù)庫(kù)HelloDjango
'NAME': 'HelloDjango',
# 用戶名
'USER': 'root',
# 密碼
'PASSWORD': '123456',
# 主機(jī)
'HOST': '127.0.0.1',
# 端口號(hào)
'POST': '3306'
}
}
三、模型開(kāi)發(fā)流程
- 配置數(shù)據(jù)庫(kù)(創(chuàng)建對(duì)應(yīng)數(shù)據(jù)砂碉,數(shù)據(jù)庫(kù)上述配置)
默認(rèn)使用sqlite!
- 定義模型類(一個(gè)模型類對(duì)應(yīng)一個(gè)表單)
class Student(models.Model): name = models.CharField(max_length=40) sex = models.CharField(max_length=10) age = models.IntegerField() isdelete = models.BooleanField(default=False)
- 生成遷移文件(
python manage.py makemigrations
)$ python manage.py makemigrations 或 $ python manage.py makemigrations appname # 刪除遷移目錄時(shí)滴某,可以使用 備注: 在migrations目錄中生成一個(gè)遷移文件滋迈,此時(shí)數(shù)據(jù)庫(kù)中還沒(méi)生成表單
- 執(zhí)行遷移文件,生成對(duì)應(yīng)表單(
python manage.py migrate
)$ python manage.py migrate 備注: 相當(dāng)于執(zhí)行了MySQL語(yǔ)句創(chuàng)建了表單(appname_students)
就算是沒(méi)有創(chuàng)建模型幕侠,也是要執(zhí)行遷移,因?yàn)槌俗约合到y(tǒng)需要在數(shù)據(jù)庫(kù)中生成對(duì)應(yīng)的表單晤硕!
- 使用模型類進(jìn)行增刪改查
# 插入數(shù)據(jù) stu = Student() stu.name = 'atom' stu.sex = '男' stu.age = 18 stu.save() # 寫入數(shù)據(jù)庫(kù)
四硕旗、ORM
- 概述
O: 對(duì)象
R: 關(guān)系
M: 映射
- 任務(wù)
- 根據(jù)對(duì)象類型生成表結(jié)構(gòu);
- 將對(duì)象、列表的操作轉(zhuǎn)換sql語(yǔ)句;
- 將sql語(yǔ)句查詢到的結(jié)果轉(zhuǎn)為對(duì)象创译、列表;
五墙基、屬性定義
- 概述
- Django根據(jù)屬性的類型確定以下信息:
當(dāng)前選擇的數(shù)據(jù)庫(kù)支持字段的類型;
渲染管理表單時(shí)使用的默認(rèn)html控件;
在管理站點(diǎn)最低限度的驗(yàn)證;
- Django的主鍵
會(huì)為表增加自增長(zhǎng)的主鍵列刷喜,每個(gè)模型只能有一個(gè)主鍵列立砸;
如果使用選項(xiàng)設(shè)置某屬性為主鍵列后,則Django不會(huì)再生成默認(rèn)的主鍵列;
- 屬性命名規(guī)則:
遵循標(biāo)識(shí)符規(guī)則;
由于Django的查詢方式颗祝,不允許使用連續(xù)的下劃線;
- 庫(kù)
- 定義屬性時(shí)
需要字段類型,字段類型是被定義在django.db.models.fields目錄下;
為了方便使用搁宾,被導(dǎo)入到django.db.models中;
- 使用方式
導(dǎo)入from django.db import models;
通過(guò)models.field創(chuàng)建字段類型的對(duì)象倔幼,賦值給屬性;
- 邏輯刪除
對(duì)于重要數(shù)據(jù)都做邏輯刪除,不做物理刪除;
實(shí)現(xiàn)方法是定義isDelete屬性损同,類型為BooleanField,默認(rèn)值為False;
- 字段類型
- AutoField
一個(gè)根據(jù)實(shí)際ID自動(dòng)增長(zhǎng)的IntegerField茂卦,通常不指定蹄梢;
如果不指定,一個(gè)主鍵字段將自動(dòng)添加到模型中;
- CharField(max_length=字段長(zhǎng)度)
字符串禁炒,默認(rèn)的表單樣式TextInput;
- TextField
大文本字段,一般超過(guò)4000使用暴备,默認(rèn)的表單控件是Textarea;
- IntegerField
整數(shù);
- DecimalField(max_digits=None, decimal_places=None)
使用python的Decimal實(shí)例表示的十進(jìn)制浮點(diǎn)數(shù);
DecimalField.max_digits: 位數(shù)總數(shù);
DecimalField.decimal_places: 小數(shù)點(diǎn)后的數(shù)字位數(shù);
- FloatField
用Python的float實(shí)例來(lái)表示的浮點(diǎn)數(shù);
- BooleanField
true/false 字段们豌,此字段的默認(rèn)表單控制是CheckboxInput;
- NullBooleanField
支持null、true望迎、false三種值;
- DateField([auto_now=False, auto_now_add=False])
使用Python的datetime.date實(shí)例表示的日期;
DateField.auto_now: 每次保存對(duì)象時(shí),自動(dòng)設(shè)置該字段為當(dāng)前時(shí)間涛浙,默認(rèn)是False;
DateField.auto_now_add: 當(dāng)對(duì)象第一次被創(chuàng)建時(shí)自動(dòng)設(shè)置當(dāng)前時(shí)間,它總是使用當(dāng)前日期,默認(rèn)是False;
auto_now_add, auto_now, and default 這些設(shè)置是相互排斥的轿亮,他們之間的任何組合將會(huì)發(fā)生錯(cuò)誤的結(jié)果;
- TimeField
使用Python的datetime.time實(shí)例表示的時(shí)間,參數(shù)同DateField;
- DateTimeField
使用Python的datetime.datetime實(shí)例表示的日期和時(shí)間按咒,參數(shù)同DateField;
- FileField
一個(gè)上傳文件的字段;
- ImageField
繼承了FileField的所有屬性和方法但骨,但對(duì)上傳的對(duì)象進(jìn)行校驗(yàn),確保它是個(gè)有效的image;
- 字段選項(xiàng)(通過(guò)字段選項(xiàng)奔缠,可以實(shí)現(xiàn)對(duì)字段的約束)
- null
如果為True,Django 將空值以NULL 存儲(chǔ)到數(shù)據(jù)庫(kù)中,默認(rèn)值是 False;
- blank
如果為True箫锤,則該字段允許為空白,默認(rèn)值是 False;
null是數(shù)據(jù)庫(kù)范疇的概念阳准,blank是表單驗(yàn)證證范疇的;
- db_column
字段的名稱馏臭,如果未指定,則使用屬性的名稱;
- db_index
若值為 True, 則在表中會(huì)為此字段創(chuàng)建索引;
- verbose_name
Admin(后臺(tái)顯示的名稱)中字段的顯示名稱;
- default
默認(rèn)值;
- primary_key
若為 True, 則該字段會(huì)成為模型的主鍵字段;
- unique
如果為 True, 這個(gè)字段在表中必須有唯一值;
- 關(guān)系
- ForeignKey:一對(duì)多括儒,將字段定義在多的端中
格式: 對(duì)象.模型類小寫_set
示例: grade.students_set
- OneToOneField:一對(duì)一,將字段定義在任意一端中
格式: 對(duì)象.模型類小寫
示例: grade.students
- 訪問(wèn)id
格式: 對(duì)象.屬性_id
示例: student.sgrade_id
- ManyToManyField:多對(duì)多乍狐,將字段定義在兩端中
外鍵: 屬于數(shù)據(jù)庫(kù)約束
外鍵默認(rèn)是可以重復(fù)的固逗,對(duì)應(yīng)另外一張表的主鍵(一對(duì)多)
六、模型查詢之基本使用
查詢集表示從數(shù)據(jù)庫(kù)獲取的對(duì)象集合烫罩。
查詢集合可以有多個(gè)過(guò)濾器。
過(guò)濾器就是一個(gè)函數(shù)盗誊,基于所給的參數(shù)限制查詢結(jié)果。
從SQL角度來(lái)說(shuō)浊伙,查詢集合與select等價(jià)嚣鄙,過(guò)濾器就像where條件。
- 查詢集
- 在管理器上調(diào)用過(guò)濾器方法返回查詢集;
- 查詢集經(jīng)過(guò)過(guò)濾器篩選后返回新的查詢集哑子,所以可以寫出鏈?zhǔn)秸{(diào)用;
- 惰性執(zhí)行(創(chuàng)建查詢集不會(huì)帶任何數(shù)據(jù)訪問(wèn),直到調(diào)用數(shù)據(jù)時(shí)才會(huì)訪問(wèn)數(shù)據(jù))
- 直接訪問(wèn)的情況
- 迭代
- 序列化
- 與if合用
- 過(guò)濾器(返回查詢集)
- all() 返回查詢集中所有數(shù)據(jù)(一條數(shù)據(jù)即一個(gè)對(duì)象)
students = Student.objects.all()
- filter() 返回符合要求的數(shù)據(jù)
filter(鍵=值)
filter(鍵=值,鍵=值)
filter(鍵=值).filter(鍵=值)
students = Student.objects.filter(s_score=91)
students = Student.objects.filter(s_score__lt=60)
- exclude() 過(guò)濾掉符合條件的數(shù)據(jù)
students = Student.objects.exclude(s_score=91)
- order_by() 排序
students = Student.objects.order_by('s_score') # 升序
students = Student.objects.order_by('-s_score') # 降序
- values() 返回查詢集中所有數(shù)據(jù)(一條數(shù)據(jù)即一個(gè)字典)帐要,返回一個(gè)列表
lt小于弥奸、lte小于等于、gt大于盛霎、gte大于等于、ne不等于
- 返回單個(gè)數(shù)據(jù)
- get() 返回一個(gè)滿足條件的對(duì)象
如果沒(méi)有找到符合條件的對(duì)象期揪,會(huì)引發(fā)'DoesNotExist'異常
如果找到多個(gè)對(duì)象规个,會(huì)引發(fā)'MultipleObjectsReturned'異常
- count() 返回查詢集的對(duì)象個(gè)數(shù)
students = Student.objects.filter(pk=1)
if students.count()>0: # 有數(shù)據(jù)
pass
else:
pass
- first() 返回查詢集中的第一個(gè)對(duì)象
student = students.first()
- last() 返回查詢集中的最后一個(gè)對(duì)象
students = students.last()
- exists() 判斷查詢集中是否有數(shù)據(jù),有數(shù)據(jù)返回True
if students.exists(): # 有數(shù)據(jù)
pass
else:
pass
students = Student.objects.get(pk=91), pk是primary key縮寫缤苫!
- 限制查詢集(切片)
查詢集返回列表,可以使用下標(biāo)的方法進(jìn)行限制榨馁,等同于sql語(yǔ)句中的limit語(yǔ)句;
例如: studentList = Students.objects.all()[0:5]
注意: 下標(biāo)不能是負(fù)數(shù)
- 查詢集緩存
- 每個(gè)查詢集都包含一個(gè)緩存帜矾,來(lái)最小化的數(shù)據(jù)訪問(wèn)
- 在新建的查詢集時(shí),緩存首次為空屡萤,第一次對(duì)查詢集求值,會(huì)發(fā)生數(shù)據(jù)緩存
- django會(huì)將查詢出來(lái)的數(shù)據(jù)做一個(gè)緩存招拙,并返回查詢結(jié)果,以后查詢直接使用查詢集的緩存
- 元選項(xiàng)
- 在模型類中定義Mata類别凤,用于設(shè)置元信息
- db_table屬性
定義數(shù)據(jù)表名规哪,推薦使用小寫字母,數(shù)據(jù)表名默認(rèn)為項(xiàng)目名小寫_類名;
- ordering屬性
對(duì)象的默認(rèn)排序字段诉稍,獲取對(duì)象的列表時(shí)使用;
ordering = ['id'] 升序
ordering = ['-id'] 降序
ordering = ['sage'] 按sage升序
注意: 排序會(huì)增加數(shù)據(jù)庫(kù)的開(kāi)銷;
# 學(xué)生表students
class Students(models.Model):
# 在沒(méi)有添加主鍵時(shí)蚤告,它會(huì)在生成時(shí)自動(dòng)添加主鍵
# id = models.IntegerField()
sname = models.CharField(max_length=30)
ssex = models.CharField(max_length=10)
sage = models.IntegerField()
sbrief = models.CharField(max_length=50)
isdel = models.BooleanField(default=False)
lastTime = models.DateTimeField(auto_now=True)
createTime = models.DateTimeField(auto_now=True)
# sclass = models.CharField(max_length=10)
# 關(guān)聯(lián)外鍵(學(xué)生都會(huì)有一個(gè)班級(jí))
sclass = models.ForeignKey('Grades')
def __str__(self):
return '%s %s' % (self.sname,self.sclass)
# 元選項(xiàng)(元信息)
class Meta:
db_table= 'students'
# ordering = ['id']
ordering = ['sage']
__str__
內(nèi)置方法服爷,一般說(shuō)明類的說(shuō)明,或者自己定義輸出仍源。
七、模型查詢之字段查詢
- 概述
- 實(shí)現(xiàn)了sql中的where語(yǔ)句,作為方法filter()终抽、excluede()、get()的參數(shù)
- 語(yǔ)法
屬性名稱__比較運(yùn)算符=值
- 外鍵
屬性名_id
- 轉(zhuǎn)義
like語(yǔ)句中使用%為了匹配占位
filter(sname__contains='%')
- 比較運(yùn)算符
- exact 判斷(大小寫敏感)
filter(isdel=False)
- contains 是否包含(大小寫敏感)
studentList = Student.objects.filter(sname__contains='孫')
- startswith匾旭、endswith 以value開(kāi)頭或結(jié)尾(大小寫敏感)
studentList = Student.objects.filter(sname__startswith='孫')
備注:
以上四個(gè)前面加上i圃郊,表示不區(qū)分大小寫;
iexact持舆、icontains、istartswith居兆、iendswith
- isnull竹伸、isnotnull 是否為空
filter(sname__isnull=False)
- in 是否包含在范圍內(nèi)
studentList = Students.objects.filter(pk__in=[2,3,4,5,6])
- gt大于、gte大于等于、lt小于魏割、lte小于等于
studentList = Students.objects.filter(sage__gt=30)
- year钢颂、mouth、day须揣、week_day、hour耻卡、minute牲尺、second 時(shí)間相關(guān)
studentList = Student.objects.filter(lastTime__year=2018)
- 跨關(guān)聯(lián)查詢 (處理join查詢)
語(yǔ)法: 模型類名__屬性名__比較符
例如: 學(xué)生描述中帶有'張三'的學(xué)生屬于哪個(gè)班級(jí)
grade = Grades.objects.filter(students__sbrief__contains='張三')
- 查詢快捷
pk 代表主鍵(因?yàn)橹麈I并不一定就是id字段)
student = Students.objects.get(pk=3)
- 聚合函數(shù)
使用aggregate()函數(shù)返回聚合函數(shù)的值【sql中的函數(shù)使用】
例如: Avg()、Count()谤碳、Max()旺垒、Min()酌住、Sum()
實(shí)例:
from django.db.models import Max
maxAge = STudents.objects.aggregate(Max('sage'))
- F對(duì)象
- 可以使用模型的A屬性與B屬性進(jìn)行比較.
例如: Grades.objects.filter(ggirlnum__gt=F('gboynum'))
- 支持F對(duì)象的算術(shù)運(yùn)算
例如: Grades.objects.filter(ggirlnum__gt=F('gboynum')+20)
- Q對(duì)象
- 概述
查詢條件的封裝
- 需求
進(jìn)行or查詢飘言、進(jìn)行and查詢旦事、進(jìn)行~查詢 【與或非操作】
- 解決
使用Q對(duì)象
- 例如
studentList = Students.objects.filter(Q(pk__lte=3) | Q(sage__gt=50))
studentList = Students.objects.filter(Q(pk__lte=3) # 只有一個(gè)Q對(duì)象就用于匹配
studentList = Students.objects.filter(~Q(pk__lte=3) # 取反
八董瞻、模型成員
- 類屬性
- objects管理器
是Manager類型的一個(gè)對(duì)象峻村,作用是與數(shù)據(jù)庫(kù)交互;
當(dāng)定義模型類是沒(méi)有指定管理器锡凝,則Django為模型創(chuàng)建一個(gè)名為objects的管理器;
- 自定義管理器
當(dāng)為模型指定模型管理器,Django就不在為模型類生成objects模型管理對(duì)象;
studentsObj = models.Manager() # 自定義模型管理器
- 模型管理器作用
模型管理器是Django的模型與數(shù)據(jù)庫(kù)進(jìn)行交互的接口张肾;
一個(gè)模型可以有多個(gè)模型管理器;
- 自定義管理器Manager類
向著管理器中添加額外的方法;
修改管理器返回的原始查詢集(重寫get_queryset());
# 自定義管理器后
# Students.objects.all() # 默認(rèn)時(shí)
Students.studentObj.all() # 自定義管理器為studentObj
<QuerySet [<Students: 韓俊 python05>, <Students: 申寶靜 python05>, <Students: 李嘉熙 python05>, <Students: 小紅 python05>, <Students: 陽(yáng)亞霞 python01>, <Students: 老王 python04>, <Students: 向芳 python01>, <Students: 哈哈 python05>, <Students: 薛延美 python01>, <Students: 孫獅勤 python05>, <Students: 呵呵 python05>, <Students: 蕭十一郎 python06>, <Students: 武含 python06>, <Students: 李明志 python04>, <Students: 王子衡 python06>, <Students: 陸彥旭 python01>, <Students: 唐李超 python04>, <Students: 郝路杰 python06>, <Students: 夏明宇 python06>, <Students: 范育賓 python01>, '...(remaining elements truncated)...']>
# 自定義管理器Manager類
class StudentsManager(models.Manager):
# 修改管理器返回的原始查詢集合
def all(self):
# 調(diào)用父類方法捌浩,在父類方法基礎(chǔ)上進(jìn)行再次過(guò)濾
return super().all().filter(isdel=False)
# 學(xué)生表students
class Students(models.Model):
# 自定義模型管理器
studentObj1 = models.Manager()
# 用到自定義管理器(對(duì)數(shù)據(jù)進(jìn)行過(guò)濾)
studentObj2 = StudentsManager()
# 使用1: Students.studentObj1.all()
# 使用2: Students.studentObj2.all()
- 創(chuàng)建模型對(duì)象
- 目的
向數(shù)據(jù)庫(kù)中添加數(shù)據(jù)
- 注意
當(dāng)創(chuàng)建對(duì)象時(shí)工秩,django是不會(huì)對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀寫操作进统;
當(dāng)調(diào)用save()方法時(shí)才會(huì)與數(shù)據(jù)庫(kù)交互浪听,將對(duì)象保存到數(shù)據(jù)庫(kù)表單中;
__init__方法已經(jīng)在父類models.Model中使用,在自定義的模型中無(wú)法使用;
- 在模型類中添加一個(gè)類方法(為了創(chuàng)建對(duì)象)
# 學(xué)生表students [models.py文件中]
class Students(models.Model):
...
# 定義一個(gè)類方法創(chuàng)建對(duì)象
@classmethod # 這表明就是類方法
def createStudents(cls,name,sex,age,brief,grade,lastT,createT,isd=False): # cls就表示Students這個(gè)類
student = cls(sname=name,ssex=sex,sage=age,sbrief=brief,sclass=grade,lastTime=lastT,createTime=createT,isdel=isd)
return student
# 調(diào)用即快速創(chuàng)建學(xué)生對(duì)象 [views.py文件中]
stu = Students.createStudents('測(cè)試數(shù)據(jù)','男',18,'我是測(cè)試數(shù)據(jù)迹栓,別太在意.',grade,'2018-05-30','2018-05-29')
- 在定義管理器中添加一個(gè)方法(為了創(chuàng)建對(duì)象)
# 自定義管理器Manager類
class StudentsManager(models.Manager):
def all(self):
# 調(diào)用父類方法克伊,在父類方法基礎(chǔ)上進(jìn)行再次過(guò)濾
return super().all().filter(isdel=False)
def createStudent(self,name,sex,age,brief,grade,lastT,createT,isd=False):
# self.model() 其實(shí)就是創(chuàng)建Students對(duì)象
stu = self.model()
stu.sname = name
stu.ssex = sex
stu.sage = age
stu.sbrief = brief
stu.sclass = grade
stu.lastTime = lastT
stu.createTime = createT
return stu
# 調(diào)用即快速創(chuàng)建學(xué)生對(duì)象 [views.py文件中]
stu = Students.studentObj2.createStudent('測(cè)試數(shù)據(jù)','男',18,'我是測(cè)試數(shù)據(jù),別太在意.',grade,'2018-05-30','2018-05-29')
十愿吹、其他
-
查詢數(shù)據(jù)
- 根據(jù)不同條件,獲取對(duì)應(yīng)的數(shù)據(jù)
-
添加數(shù)據(jù)
- 實(shí)例化模型對(duì)象 - 設(shè)置對(duì)象屬性 - 調(diào)用對(duì)象的save()方法
-
更新數(shù)據(jù)
- 查詢獲取到需要更新的對(duì)象 - 設(shè)置對(duì)象數(shù)據(jù) - 調(diào)用對(duì)象的save()方法
-
刪除數(shù)據(jù)
- 查詢獲取需要?jiǎng)h除出的對(duì)象 - 調(diào)用對(duì)象的delete()方法