1. 程式人生 > 其它 >Django ORM框架

Django ORM框架

思考:Django操作資料庫中的資料(增刪改查),都有哪些方式可以實現呢?

首先,肯定能想到的方式一:使用三方資料庫操作模組,執行原生的sql語句對資料庫進行操作,如pymysql模組,但此種方式勢必存在以下問題:

1. sql語句一般比較複雜,並且維護困難

2. sql語句的安全性無法得到保障,可能會有sql注入的風險

3. 資料庫的建立、資料表的生成、資料備份以及資料庫的遷移非常麻煩

4. sql語句效能無法保障

其次,方式二就是本篇文章主要要說的:通過ORM框架操作資料庫

在介紹ORM框架之前,先看看mysql都有哪些物件?

1. 資料庫

2. 資料表

3. 欄位

4. 記錄

那麼,ORM框架與這些物件又有什麼關係?

1. 資料庫 --> 需要提前手動建立資料庫

2. 資料表 --> 與ORM框架中的模型類一一對應

3. 欄位 --> 與ORM框架中模型類的類屬性一一對應

4. 記錄 --> 與ORM框架中模型類的例項一一對應

在通過ORM框架操作資料庫之前,需要對使用的資料庫進行配置:

1. 在全域性配置檔案settings.py的DATABASES字典中配置需要連線的資料庫資訊

2. Django預設使用的資料庫是sqlite3(關係型文字資料庫)

3. 資料庫配置格式如下:

DATABASES = {
    'default': {
        'ENGINE': '
django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }

注:

default 為資料庫的別名(標籤)

ENGINE 指定資料庫引擎,Django預設支援5種資料庫引擎:mysql、oracle、postgresql、postgresql_psycopg2,如果要使用其他的資料庫,如redis、mongo等,需要安裝對應的模組後再另行配置,此處不展開。

NAME 指定資料庫名稱,如果使用的是sqlite3,需要自定sqlite3檔案的絕對路徑

4. 配置mysql資料庫資訊示例:

DATABASES = {
    
'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysqlDB', 'USER': 'root', 'PASSWORD': '123456', 'PORT': 3306, 'HOST': '127.0.0.1' } }

方便起見,我用的是Django預設資料庫sqlite3,配置資訊沒有更改

PS:使用編輯器pycharm連線sqlite資料庫示例

配置完資料庫資訊,就可以定義模型類了:

1. 一般在子應用的models.py檔案中定義模型類(相當於資料庫中的一張表)

2. 模型類必須繼承Model或者Model的子類

3. 模型類中定義的類屬性(相當於資料表中的欄位),必須是Field的子類

class Projects(models.Model):
    name = models.CharField(max_length=50, verbose_name="專案名稱", help_text="專案名稱", unique=True)
    leader = models.CharField(max_length=10, verbose_name="專案負責人", help_text="專案負責人")
    is_execute = models.BooleanField(verbose_name="是否啟動專案", help_text="是否啟動專案", default=True)
    desc = models.TextField(verbose_name="專案描述資訊", help_text="專案描述資訊", null=True, blank=True, default='')
    create_time = models.DateTimeField(verbose_name="建立時間", help_text="建立時間", auto_now_add=True)
    update_time = models.DateTimeField(verbose_name="更新時間", help_text="更新時間", auto_now=True)

    class Meta:
        db_table = "tb_projects"

4. 定義類屬性時,常用的Field子類:

  1)CharField --> varchar

  2)IntegerField--> integer

  3)BooleanField--> bool

  4)TextField--> longtext

  5)DateTimeField--> datetime

  ......

5. 定義類屬性時,field子類常用options:

  1)verbose_name:admin後臺中該欄位的別名

  2)help_text:通過表單小部件來展示該欄位額外的help資訊,值一般與verbose_name保持一致即可

  3)unique:該欄位設定唯一約束,預設值為False

  4)default:為該欄位設定預設值

  5)blank:該欄位是否允許前端傳遞空字串,預設值為False

  6)null:該欄位是否允許前端傳遞null,預設值為False

  7)auto_now:DateTimeField的例項引數,儲存資料時該欄位值會自動儲存為當前時間,每次執行save方法時都會將當前時間儲存

  8)auto_now_add:DateTimeField的例項引數,建立資料時該欄位值會自動儲存為當前時間,之後更新資料該欄位值不會再更新

6. 可以在任意一個模型類中定義Meta內部類,用於修改資料庫的元資料資訊,如:

  1)在Meta內部類中,定義類屬性 db_table 的值,即為該模型類對應生成的資料表的表名;

  2)在Meta內部類中,定義類屬性 verbose_name 的值,即為該模型類對應生成的資料表的描述資訊;

  3)在Meta內部類中,定義類屬性 abstract=True ,指定當前模型類為抽象模型類,在遷移時不會生成資料表;

  4)在Meta內部類中,定義類屬性 ordering=['欄位名'] ,指定該模型類對應生成的資料表資料的排序欄位,預設按照id排序

7. 表與表之間的關聯關係的定義

  1)ForeignKey --> 一對多,一般在‘多’的那個模型類中定義外來鍵欄位,如:一個專案會有多個介面,一般在介面表中定義外來鍵欄位

   必傳引數:to ,即和誰建立外來鍵關係,有三種傳值方式:

       第一種:匯入要建立外來鍵關係的模型類(一般稱為主表模型類),傳遞該模型類的引用;

       第二種:字串,子應用名.模型類名,此種方式無需匯入

       第三種:字串,self,表示自關聯(自己關聯自己)

   必傳引數:on_delete ,即指定主表資料刪除後,從表資料的刪除策略

       model.CASCADE 主表資料刪除後,相應的從表資料也刪除

       model.SET_NULL 主表資料刪除後,相應的從表資料設定為null,前提:從表字段必須設定null=True

       model.SET_DEFAULT 主表資料刪除後,相應的從表資料設定為預設值,前提:從表字段必須設定預設值default=xx

       model.PROTECT 主表資料刪除時,如果從表有對應的資料,則會報錯

class Interfaces(models.Model):
    name = models.CharField(max_length=50, verbose_name="介面名稱", help_text="介面名稱", unique=True)
    tester = models.CharField(max_length=10, verbose_name="測試人員", help_text="測試人員")
    desc = models.TextField(verbose_name="介面描述資訊", help_text="介面描述資訊", null=True, blank=True, default='')
    create_time = models.DateTimeField(verbose_name="建立時間", help_text="建立時間", auto_now_add=True)
    update_time = models.DateTimeField(verbose_name="更新時間", help_text="更新時間", auto_now=True)
    projects = models.ForeignKey("projects.Projects", on_delete=models.CASCADE, verbose_name="所屬專案", help_text="所屬專案")

    class Meta:
        db_table = "tb_interfaces"
        verbose_name = "介面表"
        verbose_name_plural = "介面表"

  2)ManyToManyField --> 多對多,可以在任意一個模型類中使用ManyToManyField

  3)OneToOneField --> 一對一,可以在任意一個模型類中使用OneToOneField

8. Django模型類轉化為資料表

  1)生成遷移指令碼:進入專案虛擬環境,執行命令 python manage.py makemigrations 子應用名

  注:如果不指定子應用名,會把所有子應用都生成遷移指令碼

檢視生成的遷移指令碼內容,如下圖

注:定義模型類時,未定義主鍵,預設會自動建立一個名為id的自增主鍵。

2)執行遷移指令碼:進入專案虛擬環境,執行命令 python manage.py migrate 子應用名

注:生成的資料表名預設為:子應用名_模型類名小寫;如果內部類Meta中定義了db_table屬性,則資料表名為db_table的值

對定義了外來鍵欄位的模型類進行遷移,並檢視生成的資料表中外來鍵欄位的顯示

外來鍵欄位名顯示為:模型類中定義的外來鍵欄位名_id

可以使用命令 python manage.py sqlmigrate 子應用名 遷移指令碼名 來檢視遷移指令碼生成的sql語句

9. BaseModel的定義:

  1)目的:精簡模型類程式碼,將公共欄位抽取出來,定義在BaseModel中,需要用到公共欄位的模型類,繼承BaseModel即可

  2)BaseModel 沒有必要生成資料表,需要在定義BaseModel時,在其內部類Meta中設定abstract=True,即表明當前模型類為抽象模型類,遷移時不會建立表,僅僅用於其他模型類繼承

  3)位置:一般會建立utils包,將BaseModel定義在此包中

本部落格僅為本人學習過程中的記錄,歡迎一起交流經驗。