簽名設(shè)計(jì)免費(fèi)版西安搜索引擎優(yōu)化
Django的模型層1.Model的開發(fā)流程2.定義Model模型3.Model模型的實(shí)例4.Model模型的實(shí)戰(zhàn)操作筆記開發(fā)流程1.在models.py中定義模型類,要求繼承自models.Model2.生成遷移文件3.執(zhí)行遷移5.定義屬性1.字段類型2.字段選項(xiàng)3.關(guān)系模型實(shí)例1.類的屬性2.創(chuàng)建對(duì)象3.實(shí)例的屬性模型查詢1.查詢集2.限制查詢集3.查詢集的緩存4.字段查詢1.比較運(yùn)算符2.跨關(guān)聯(lián)關(guān)系的查詢:處理join查詢3.聚合函數(shù)
Django的模型層
模型是項(xiàng)目中的數(shù)據(jù)消息源,它包含著儲(chǔ)存數(shù)據(jù)的必要字段和行為
通常,每個(gè)模型對(duì)應(yīng)數(shù)據(jù)庫中的一張表,每個(gè)屬性對(duì)應(yīng)一個(gè)字段
每個(gè)模型都是Django.db.models.Model的一個(gè)Python子類
Django提供一套自動(dòng)生成的用于數(shù)據(jù)庫訪問的API
模型與數(shù)據(jù)庫的關(guān)系是ORM關(guān)系(對(duì)象-關(guān)系-映射)
為什么要使用模型?
Model是MVC框架中的重要一部分,負(fù)責(zé)在數(shù)據(jù)庫中存取數(shù)據(jù),它實(shí)現(xiàn)了數(shù)據(jù)庫與數(shù)據(jù)模型的解耦,即不需要特定的數(shù)據(jù)庫,通過簡單的配置就可以輕松的更換數(shù)據(jù)庫
1.Model的開發(fā)流程
-
在應(yīng)用的models.py中定義的模型類,要求集成自models.Model
-
把應(yīng)用加入到項(xiàng)目settings.py配置文件中的INSTALLED_APPS中
-
生成遷移文件
python manage.py makemigrations
-
執(zhí)行遷移
python manage.py migrate
-
使用模型類進(jìn)行CRU操作
2.定義Model模型
-
在模型類中定義屬性,會(huì)生成表中的字段
-
Django根據(jù)屬性的類型確定以下信息:
-
當(dāng)前選擇的數(shù)據(jù)庫支持字段的類型
-
渲染管理表單數(shù)據(jù)時(shí)使用的默認(rèn)html控件
-
在管理站點(diǎn)最低限度的驗(yàn)證
-
-
Django會(huì)為表增加自動(dòng)生長的主鍵列,每個(gè)模型只能有一個(gè)主鍵列
-
屬性命名限制
-
不能是python的保留關(guān)鍵字
-
由于Django的查詢方式,部允許使用連續(xù)的下劃線
-
3.Model模型的實(shí)例
-
模型實(shí)例對(duì)象就是通過objects屬性獲取,即Django為模型提供的管理類
objects:是Manage類型的對(duì)象,用于和數(shù)據(jù)庫進(jìn)行交互
-
實(shí)例的方法
-
str(self):重寫object方法,此方法在將對(duì)象轉(zhuǎn)換成字符串時(shí)會(huì)被調(diào)用
-
save():將模型對(duì)象保存到數(shù)據(jù)表中
-
delete():將模型對(duì)象從數(shù)據(jù)表中刪除
-
4.Model模型的實(shí)戰(zhàn)操作筆記
開發(fā)流程
1.在models.py中定義模型類,要求繼承自models.Model
class User(models.Model):id = models.AutoField(primary_key=True, verbose_name='主鍵') ? ? ? ?# 主鍵可以不用寫name = models.CharField(max_length=32, verbose_name='用戶名')age = models.IntegerField(verbose_name='年齡',default=20)phone = models.CharField(max_length=11, verbose_name='手機(jī)號(hào)')add_time = models.DateTimeField(default=datetime.now) ?class Meta:db_table = 'myapp_user' ? ? ? ?# 表名,默認(rèn)為應(yīng)用名_類名小寫 ?def __str__(self):return self.name ?
2.生成遷移文件
python manange.py makemigrations ? ? # 執(zhí)行結(jié)果 C:\Users\Administrator\Desktop\Python開發(fā)\myweb>python manage.py makemigrations Migrations for 'myapp':myapp\migrations\0002_auto_20210921_1611.py- Create model User- Change Meta options on stu
3.執(zhí)行遷移
python manange.py migrate ? # 執(zhí)行結(jié)果 ? C:\Users\Administrator\Desktop\Python開發(fā)\myweb>python manage.py migrate Operations to perform:Apply all migrations: admin, auth, contenttypes, myapp, sessions Running migrations:Applying myapp.0002_auto_20210921_1611... OK
5.定義屬性
-
定義屬性時(shí),需要字段類型
-
字段類型被定義在django.db.models.fields,為了方便使用,被導(dǎo)入到django.db.models中
-
使用方式
-
導(dǎo)入from django.db import models
-
通過models.Field創(chuàng)建字段類型的對(duì)象,賦值給屬性
-
-
對(duì)于重要的數(shù)據(jù),要做邏輯刪除,不做物理刪除,實(shí)現(xiàn)方法是定義isDelete屬性,類型為BooleanField,默認(rèn)為False
1.字段類型
-
AutoField:一個(gè)根據(jù)實(shí)際的ID最低頂增長的interField,通常不指定
-
如果不指定,一個(gè)主鍵將自動(dòng)添加到模型中
-
-
BooleanField:true/false字段.此字段的默認(rèn)表單控制是Checkboxinput
-
NullBooleanField:支持null,true,false三種值
-
CharField(max_length=字段長度):字符串,默認(rèn)的表單數(shù)據(jù)是Textinput
-
IntergerField:整數(shù)
-
TextField:大文本字段,一般超過4000使用,默認(rèn)的表單控件是Textarea
-
DecimalField(max_digits=None,decimal_palces=None):使用python的Decimal實(shí)例表示扽 十進(jìn)制浮點(diǎn)數(shù),一般用于金錢
-
max_digits:位數(shù)總數(shù)
-
decimal_palces:小數(shù)點(diǎn)后的數(shù)字位數(shù)
-
-
FloatField:用python的實(shí)例來表示的浮點(diǎn)數(shù)
-
DateField(auto_now=False,auto_now_add=False):使用python的datatime.data實(shí)例表示的日期
-
參數(shù)DateField.auto_now:表示保存日期時(shí),自動(dòng)設(shè)置該字段為當(dāng)前時(shí)間,用于最后一次修改的時(shí)間戳,它總是使用當(dāng)前的日期,默認(rèn)為False
-
參數(shù)DateField.auto_nowDateField.auto_now_add:當(dāng)對(duì)憲法第一次被創(chuàng)建時(shí)使用當(dāng)前時(shí)間,用于創(chuàng)建的時(shí)間戳,它總是使用當(dāng)前的日期,默認(rèn)為False
-
該字段默認(rèn)的對(duì)應(yīng)表單控件是一個(gè)Textinput:在管理員站點(diǎn)添加一個(gè)javaScript寫的日志控件,和一個(gè)Today的快捷按鈕,它包含了一個(gè)額外的invalid_data錯(cuò)誤消息鍵
-
-
TimeField:使用python的datatime實(shí)例表示的時(shí)間,參數(shù)同DateField
-
DateTimeField:使用的datetime.datetime實(shí)例表示的日期和時(shí)間,參數(shù)同DateFiled
-
FieField:一個(gè)上傳文件的字段
-
ImageField:繼承了FileField的所有屬性和方法,但是對(duì)于上傳對(duì)象進(jìn)行校驗(yàn),確保是個(gè)有效的image
2.字段選項(xiàng)
-
通過字段選項(xiàng),可以實(shí)現(xiàn)對(duì)字段的約束
-
在字段對(duì)象時(shí)通過關(guān)鍵字參數(shù)指定
-
null:如果為True,Django將空值以NULL存儲(chǔ)到數(shù)據(jù)庫中,默認(rèn)是False
-
black:如果為True,則該字段允許為空白,默認(rèn)是False
-
對(duì)比:null是數(shù)據(jù)庫范疇的概念,black是表單驗(yàn)證范疇的
3.關(guān)系
-
關(guān)系的類型包括
-
Foreignkey:一對(duì)多,將字段定義在多的端中
-
ManyToManyField:多對(duì)多,阿靜字段定義在兩端中
-
OneToOneFiled:一對(duì)一,將字段定義在任意一端中
-
-
可以維護(hù)遞歸的關(guān)聯(lián)關(guān)系,使用self指定,即為自關(guān)聯(lián)
-
用一訪問多:對(duì)象.模型類小寫_set
bookinfo.heroinfo_set
-
用一訪問一:對(duì)象.模型類小寫
heroinfo.bookinfo
-
訪問id:對(duì)象.屬性_id
heroinfo.bookinfo
模型實(shí)例
1.類的屬性
-
objects:是Mnanager類型的對(duì)象,用于和數(shù)據(jù)庫進(jìn)行交互
-
當(dāng)定義模型類時(shí)沒指定管理器。那么django會(huì)為模型類生成名為objects的管理器
-
支持明確指定模型類的管理器
class Book(models.Model):books = models.Manager()
-
當(dāng)為模型類指定管理器后,django不再為默心累生成名為object的默認(rèn)管理器
2.創(chuàng)建對(duì)象
-
當(dāng)創(chuàng)建對(duì)象時(shí),django不會(huì)對(duì)數(shù)據(jù)庫進(jìn)行讀寫操作
-
調(diào)用save()方法才與數(shù)據(jù)庫進(jìn)行交互,將對(duì)象保存到數(shù)據(jù)庫中
-
說明:init方法已經(jīng)再模型類中使用,再自定義模型中無法使用
3.實(shí)例的屬性
-
DoesNotExit:在進(jìn)行單個(gè)查詢時(shí),模型的對(duì)象不存在時(shí)會(huì)引發(fā)異常,結(jié)合try/except使用
from ?myapp.models import User ? ? def index(request):# 添加操作ob = User() ? ? ? ? ? ? ? ? ? # 實(shí)例化新對(duì)對(duì)象 ? ? ? ob.name = '張三'ob.age = 20ob.mobile = '13999999999'ob.save() ? ? ? ? ? ? ? ? ? ? return HttpResponse('首頁') ? # 新對(duì)象就是添加,已存在對(duì)象就是修改# 刪除操作 ? ? ? ? ? ? ? ? ? ? # 等價(jià)于 User.objects.get(id=6).delete()mod = User.objects ? ? ? ? ? ?# 獲取users的model對(duì)象user = mod.get(id=1) ? ? ? ? ?# 獲取id為6的數(shù)據(jù)信息user.delete() ? ? ? ? ? ? ? ? # 執(zhí)行刪除操作 # 修改操作ob = Users.objects.get(id=2)ob.name = '張子怡'ob.age = 19ob.save()
模型查詢
-
查詢集表示從數(shù)據(jù)庫中獲取的對(duì)象的集合
-
查詢集可以含有零個(gè),一個(gè)或者多個(gè)過濾器
-
過濾器基于所給的參數(shù)的限制查詢的結(jié)果
-
從Sql的角度,查詢集和select語句等價(jià),過濾器像where和limit子句
1.查詢集
-
在管理器上調(diào)用過濾器會(huì)返回查詢集合
-
查詢集經(jīng)過過濾器刪選后返回新的查詢集,因此可以寫成鏈?zhǔn)竭^濾
-
創(chuàng)建查詢及不會(huì)帶來任何數(shù)據(jù)庫的訪問,直到調(diào)用數(shù)據(jù)時(shí),才會(huì)訪問數(shù)據(jù)庫
-
何時(shí)對(duì)查詢求值:迭代,序列化,與if合用
-
返回查詢集的方法,稱為過濾器
-
all()
-
filter()
-
exclude()
-
order_by()
-
values():一個(gè)對(duì)象構(gòu)成一個(gè)字典,然后構(gòu)成一個(gè)列表返回
-
-
寫法:
filter(鍵1 = 值1,鍵2=值2) 等價(jià)于 filter(鍵1=值1).filter(鍵2=值2) ?
-
返回單個(gè)值的方法
-
get():返回單個(gè)滿足條件的對(duì)象
-
如果未找到會(huì)引發(fā)'模型類.DoesNotExist'異常
-
如果多條被返回,會(huì)引發(fā)模型類.MultipleObjectsReturned異常
-
-
count():返回當(dāng)前查詢的總條數(shù)
-
first():返回第一個(gè)對(duì)象
-
last():返回最后一個(gè)對(duì)象
-
exits();判斷查詢集中的是否有數(shù)據(jù),如果有則返回True
-
-
# 查詢mod = Users.objects # 獲取User模型操作對(duì)象ulist = mod.all() # 查詢所有ulist = Users.objects.filter(name='馬小寧') ? ? ? ? # 查詢馬小寧的所有信息ulist = mod.filter(age__gt=20) ? ? ? ? ? ? ? ? ? ? # 查詢年齡大于24的所有人ulist = mod.filter(age__gte=20) ? ? ? ? ? ? ? ? ? # 查詢年齡大于等于20歲的所有人ulist = mod.filter(age__lt=20) ? ? ? ? ? ? ? ? ? ? # 查詢年齡小于20的人ulist = mod.order_by('age') ? ? ? ? ? ? ? ? # 按照年齡升序排列,默認(rèn)為升序,降序即為-ageulist = mod.all()[::2] ? ? ? ? ? ? ? ? ? ? # 只獲取前兩條
2.限制查詢集
-
查詢集返回列表,可以使用下標(biāo)的方式進(jìn)行,等同于sql中的limit和offset語句
-
注意:這里不支持附屬索引
-
使用下標(biāo)后會(huì)返回一個(gè)新的查詢集,不會(huì)立即執(zhí)行查詢
-
如果獲取一個(gè)對(duì)象,直接使用[0],等同于[0:1].get(),但是如果沒有數(shù)據(jù),[0]引發(fā)indexError異常,[0:1].get()引發(fā)DoseNotExits異常
# 這會(huì)返回前五個(gè)對(duì)象 LIMIT 5 Entry.objects.all()[::5] # 這阿靜返回第六個(gè)到第十個(gè)對(duì)象 offset 5 limit 5 Entry.object.all()[5:10]
3.查詢集的緩存
-
每個(gè)查詢集都包含一個(gè)緩存來最小化數(shù)據(jù)庫的訪問
-
在新建的查詢集中,緩存為空,首次對(duì)查詢集合求值時(shí),會(huì)發(fā)生數(shù)據(jù)庫的查詢,django會(huì)將查詢集求值將重用緩存的結(jié)果
-
情況一:這將會(huì)構(gòu)成兩個(gè)查詢集,無法重用緩存,每次查詢都會(huì)與數(shù)據(jù)庫進(jìn)行一次交互,增加了數(shù)據(jù)庫的負(fù)載
print([e.title for e in Enter.objeccts.all()]) print([e.title for e in Enter.objeccts.all()])
-
情況二:兩次循環(huán)使用同一個(gè)查詢集,第二次使用緩存中的數(shù)據(jù)
querylist = Entry.objects.all() print([e.title for e in querylist)]) print([e.title for e in querylist])
-
何時(shí)查詢集不會(huì)被緩存,當(dāng)只對(duì)查詢集的部分進(jìn)行求值時(shí)會(huì)檢查緩存,但是如果這部分不在緩存中,那么接下來查詢返回的記錄將不會(huì)被緩存,這意味著使用索引來限制查詢集將不會(huì)填充緩存,如果這部分?jǐn)?shù)據(jù)已經(jīng)被緩存,則直接使用緩存中的數(shù)據(jù)
4.字段查詢
-
實(shí)現(xiàn)where子名,作為查詢方法filter(),get()的參數(shù)
-
語法:屬性名稱__比較運(yùn)算符 = 值
-
表示兩個(gè)下劃線,左側(cè)是屬性名稱,右側(cè)是比較類型
-
對(duì)于外鍵,使用"屬性名_id"表示外鍵的原始值
-
轉(zhuǎn)義:like語句中使用了%與,匹配數(shù)據(jù)中的%與,在過濾器中直接寫,例如:
filter(title__contains = "%") =>where title like '%%%',表示直接找標(biāo)題中包含%的
1.比較運(yùn)算符
-
exact():表示判等,大小寫敏感,如果沒有寫'比較運(yùn)算符',表示判等
filter(isDelete=False)
-
contains:是否包含,大小寫敏感
filter(name_contains='小寧') ? ? ? # 名字中包含小寧 ?
-
startwith,endwith:以value開頭或者結(jié)尾,大小寫敏感
filter(phone_startwith='3') ? ? ? # 手機(jī)號(hào)碼以3開頭
-
isnull,isnotnull:是否為null
filter(name__isnull=False) ? ? ? ?# 名字不允許為空
-
在前面加i表示不區(qū)分大小寫,比如icontains,istartwith
-
in:是否包含在范圍內(nèi)
filter(pk__in = [1,2,3,4])
-
gt 、gte、 lt、 lte:大于,大于等于, 小于, 小于等于
-
year、month、day、week_day、hour、minute、second:對(duì)日期間類型的屬性進(jìn)行運(yùn)算
filter(bpub_date_year = 1980) filter(bpub_date_gt = date(1980,12,31))
2.跨關(guān)聯(lián)關(guān)系的查詢:處理join查詢
-
語法:模型類名<屬性名><比較>
-
注:可以沒有__<比較>部分,表示等于,結(jié)果同inner join
-
可以返回使用,即在關(guān)聯(lián)的兩個(gè)模型類中都可以使用
filter(heroinfo__hcontent__contains='小寧')
3.聚合函數(shù)
-
使用aggregate函數(shù)返回聚合函數(shù)的值
-
函數(shù):Avg,Count,Max,Min,Sum
from django.db.models import Max maxDate = list.aggregate(Max('bpub_date'))