django模型詳解(四)
阿新 • • 發佈:2018-06-17
imp 參數 des 也會 超過 分類 空白 fault note
1 概述
(1)概述 : Django對各種數據庫提供了很好的支持,Django為這些數據庫提供了統一的調用API,根據不同的業務需求選擇不同的數據庫
(2)定義模型
模型,屬性,表,字段間的關系
一個模型類對應數據庫的一張表,在模型類中定義屬性,對應模型對照表的字段配置數據庫
(3)django開發流程:
1 配置數據庫
2 定義模型類 : 一個模型類一張數據表
3 生成遷移文件 : 註意模型不能為空
4 執行遷移文件生成數據表
5 使用模型類進行增刪改查
2 ORM
(1)ORM概述 :o--對象 R--關系 M--映射
作用 :Django --- ORM模型(對象映射關系)生成執行語句 --- 調用mysql ,split.oracle
(2)ORM執行處理操作
根據對象的類型生成數據表結構
將對象,列表的操作轉換為sql語句
將sql語句查詢到的結果轉為對象或列表
(3)優點
極大減輕開發人員的工作量,不需要面對因數據庫的變更而修改代碼
3 定義屬性
#(1)概述
django根據屬性類型確定
當前數據庫支持的字段類型
渲染管理表單時使用的默認html控件
在管理站點最低限度的驗證
django表為表增加自動增長的主鍵列,每個模型對應一個主鍵列
屬性命名
不能是python保留關鍵字
不允許使用連續下劃線
#(2)庫繼承db.models
定義屬性需要字段類型,定義在django.db.models.field目錄下,為方便使用被導入到django.db.models中
使用方式:
from django.db import models
通過models.Field創建的字段類型的對象,賦值給屬性
#(3)邏輯刪除
對於重要數據都做邏輯刪除,不做物理刪除
實現方法:定義isDelete屬性,類型為BooleanField,默認為false
#(4)字段類型
AutoField 自動設置主鍵,主鍵字段會添加到表
CharField(max_length=字符長度) 字符串,默認表單樣式為TextInput
TextField 大文本字段,一般超過4000 使用,默認表單為Textarea
IntgerField 整數
DecimalField(max_digits=None,decimal_places=None) 十進制浮點數,小數
max_digits 位數總數
decimal_places 小數點後的位數
FloatField 用python的float實例表示浮點數
BlooeanField 布爾型 True/Flase 字段 此字段默認表單是CheckboxInput
NullBooleanField 支持True false null三種字段
DateField 日期 使用Python中的dateTime.date
TimeFiled 時間
DateTimeField 日期+時間
FileField 上傳文字的字段
ImageField 繼承FileFiled的所有屬性與方法,但對上傳對象進行校檢
#(5)字段選項
概述 : 通過字段選項可以實現對字段的約束
通過字段對象時通過關鍵字運行參數指定
null Django將空值以null形式存儲到數據庫,默認false
blanke 如果為True,字段允許空白,表單驗證範疇
db_column 字段名稱,未指定使用屬性名稱
db.index 值為true,則在表中為此字段創建索引
default 默認值
primary_key 若為true ,則字段成為模型主鍵字段
unique 如果為True 字段在表中必須有唯一值
#(6)關系
分類
ForeignKey 一對多,將字段定義在多的類中
ManyToManyField 多對多,將字段定義在兩端中
OneToOneField 一對多,將字段定義在任意一端
#(7)一對多正反向查詢
一對多訪問:
對象.模板類小寫_set
grade.students_set.屬性
多訪問一:
對象.模板類小寫.屬性
Students.objects.get(pk=2).grades.gname
#(8)一對一正反向查詢
用一對一訪問:
對象.被關聯class小寫
grade.students.sname
一對一反向查詢:
對象名.關聯對象類名小寫.屬性
students.grades.gname
#(9)多對多正反向查詢
多對多訪問:
對象.關聯字段
多對多反向查詢:
對象.被關聯對象class小寫_set
4 創建模型類: 元選項
在模型類紅定義的一個Meta類,用於設置原信息
db_table
定義數據表名,推薦使用小寫字母,不寫數據表明默認:項目名小寫_類名小寫
class Meta:
db_table = ‘student‘
ordering = [‘id‘] 在模型類中定義子類
ordering
對象默認的排序字段,獲取對象的列表時使用
ordering[id]
升序
ordering[-id]
降序
5 類屬性
(1)隱藏類屬性objects
objects 是Manager類型的一個對象,主要是實現與數據庫的交互
當定義模型類時,沒有指定管理器,則Django為模型創建一個objects管理器
(2)自定義管理器
自定義模型管理器 :
class Student(models.Model)
stuObj = models.Manager()
默認模型管理器objects就不適用: student.object.Manager
(3)自定義管理器Manager類
模型管理器django模型進行與數據庫進行交互的接口,一個模型類可以定義多個模型管理器
作用
向管理器類中添加額外的方法
修改管理器返回的原始集合(查詢集) : 通過重寫方法get_queryset()方法
代碼
class StudentsManager(models.Manager): #自定義StudentManager類
def get_queryset(self): #重寫獲取對象集方法
#返回父類原始集篩選後的查詢集
return super(StudentManager,self).filter(isDelete = False)
class StudentManage(models.Model)
#重新生成的stuObj對象
stuObj2 = StudentManager()
6 創建對象
創建對象
目的 : 向數據庫中添加數據
當創建對象時,django不會對數據庫進行讀寫操作,當調用save()方法時,才開始進行交互,將對象保存到數據庫表中
註意: __init__方法已經在父類models.Model中使用,在自定義的模型中無法使用
方法
在模型類中增加一個類方法用以創建對象
#model.py中創建類方法
class Student(modelsModel):
@classmethod #裝飾器中引入cls方法
def createStudent(cls,name,age,gender,grade)
stu = cls(sname=name,sage=age,sgender=gender,sgrade=grade)
return stu
#view.py 中創建添加學生函數
def addstudent(request):
grade = Grades.objects.get(pk=1)
stu = Student.createStudent(‘tom‘,20,True,grade)
stu.save()
return HttpResponse(‘創建成功‘)
url.py中采用正則匹配
urlpatterns = [
url(r‘‘^addstudent/$‘‘,views.addstudent) #匹配到view中對應的addstudent方法
]
#在自定義管理器添加方法
在models.py中類StudentManager類中定義方法
class StudentManager(models.Manager):
def get_queryset(self):
return super(StudentManager,self).get_queryset().filter(isDelete=True)
def createStudent(self,name,age,gender):
stu = self.model()
stu.sname = name
stu.sage = age
stu.sgender=gender
#在view.py視圖中添加方法:
def student2(request):
grade = Grades.objects.get(pk=1)
stu = Student.stuObj2.createStudent(‘andy‘,34,True)
stu.save()
return HttpResponse(‘創建成功‘)
#在urls.py路由中添加正則:
url(r‘^addstudent2/$‘,views.addstudent)
7 模型查詢
概述
1 查詢集:表示從數據庫中獲取的對象的集合
2查詢集可以有多個過濾器
3過濾器就是一個函數,基於所給的參數限制查詢的結果,類似where語句
4 查詢集等同select語句
1 在管理器上調用過濾器方法查詢
2 查詢集經過過濾器篩選後返回新的查詢集,可以鏈式調用
3 惰性執行
創建查詢集不會帶來任何數據庫的訪問直到調用數據庫才會訪問
#4 直接訪問數據
叠代
序列化
與if合用
#5 返回查詢集的方法稱為過濾器
all()
返回所有對象
filter()
filter(鍵=值,鍵=值) 且關系
返回符合條件的數據
filter(鍵=值),filter(鍵=值)
exclude()
過濾掉符合條件數據
order_by()
排序
values()
一條數據就是是一個對象(字典),返回一個列表
#6 返回單個數據
get()
返回一個滿足條件的對象
註意:沒有找到符合條件的對象,模型類引發異常 模型類.DoesNotExists異常
如果找到多個對象也會引發異常 模型類.MultipleObjectsReturned
count()
返回查詢集中的對象個數
first()
返回第一個查詢集對象
last()
返回最後一個查詢集對象
exists()
查詢集是否有數據,如果有數據返回true
#7 限制查詢集
查詢集返回的是列表,可以采用下標的方法進行限制,等同於sql中的limit語句
註意下標不能為負
studentList = Student.objects.all()[0:5]
#8 查詢集的緩存
概述 :每個查詢集都包含一個緩存,來最小化的對數據庫訪問,在新建的查詢集中,緩存首次為空,第一次對查詢集求值,django會將數據緩存,並返回結果,以後結果直接使用緩存集的數據
8 字段查詢
#(1)概述
實現where語句,作為filter() exclude() get()的參數
語法
屬性名稱__運算符 = 值
外鍵
屬性名_id
轉義
類似like語句,是為了匹配占位,匹配數據中的%,sql中where like ‘\%‘
filter(sname__contains = ‘%‘)
#(2)比較運算符
exact
判斷,大小寫敏感
filter(isDelete=False)
contains
是否包含,大小寫敏感
stuList = Student.objects.filter(sname__contains =‘孫‘ )
startswith
以value開頭,大小寫敏感
stuList = Student.objects.filter(sname__startswith =‘孫‘ )
endwith
以value結尾,大小寫敏感
isnull ,isnotnull 是否為空
filter(sname__isnull=Flase)
in
是否包含在範圍內
filter(pk__in=[2,4,6,8,10])
#(3)運算符
gt 大於
gte 大於等於
lt 小於
lte 小於等於
filter(sage_gt=30)年齡大於30
year month day week_day hour minute second
filter(lastTime__year=2017)
跨關查詢 : 處理join查詢 模型類型__屬性名__運算符(可選)
查詢快捷 : pk 代表的主鍵
iexact,icontains,istartswith,iendswith
以上四個前面加上i,就表示不區分大小寫
9 聚合函數
#(1)使用aggregate()函數返回聚合函數的值
Avg Count Max Min sum
from dango.db.models import Max
maxAge = Student.objects.aggregate(Max(‘sage‘)) 找出學生年齡最大的
#(2)F對象
1 可以使用模型的A屬性與B屬性進行比較
from django.db.models import F,Q
def grades(request):
g = Grades.objects.filter(ggirlnum_gt=F(‘gboynum‘)) 找到女生人輸大於男生人數的班級
2 支持F對象的算術運算 filter(ggirlnum_gt=F(‘gboynum‘)+20)
3 F對象的參數可以是跨表字段
models.Book.objects.filter(bread_num=F(‘‘author_name‘))
4 F對象參數如果是date/time,可以進行日期的加減運算:
models.Book.objects.filter(bpub_date__lt=F(‘bpub_date‘) + timedelta(days=5))
#(3)Q對象
概述 :過濾器的方法中的關鍵字參數,,條件為And模式,采用邏輯或引入Q對象
需求 : 進行or查詢
解決 : 使用Q對象
Q對象可以使用&(and)、|(or)操作符組合起來
studentList = Student.objects.filter(Q(pk__lt = 3)|Q(sage__gt=50))
models.User.objects.filter(Q(username=‘老王‘) & Q(userpass=‘admin‘)) 條件與組合
models.User.objects.filter(~Q(username=‘老王‘)) 條件非表示取反
可以使用&|~結合括號進行分組,構造更復雜的Q對象
filter函數可以傳遞一個或多個Q對象作為位置參數,如果有多個Q對象,這些參數的邏輯為and
studentList = Student.objects.filter(Q(pk__lt = 3) 只有 一個Q對象就是單純匹配
studentList = Student.objects.filter(~Q(pk__lt = 3) 表示對Q對象取反
django模型詳解(四)