天天看點

django模型詳解(四)

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對象取反