1. 程式人生 > >Django框架--六--資料庫

Django框架--六--資料庫

㈠簡介:

Django 對各種資料庫提供了很好的支援,包括:PostgreSQL、MySQL、SQLite、Oracle。

Django 為這些資料庫提供了統一的呼叫API。 我們可以根據自己業務需求選擇不同的資料庫。

MySQL 是 Web 應用中最常用的資料庫。本章節我們將以 Mysql 作為例項進行介紹。你可以通過本站的 MySQL 教程 瞭解更多Mysql的基礎知識。

django中內嵌了ORM框架,不需要直接面向資料庫程式設計,而是定義模型類,通過模型類和物件完成資料表的增刪改查操作。

使用django進行資料庫開發的步驟如下:

  1. 配置資料庫連線資訊
  2. 在models.py中定義模型類
  3. 遷移
  4. 通過類和物件完成資料增刪改查操作

㈡配置:

1. 使用MySQL資料庫首先需要安裝驅動程式:
ORM框架只能將模型類的操作轉換為sql語句,但是不能傳送到mysql服務端,所以需要驅動將資料進行傳送和接收,
但是,django的ORM框架只能識別 mysqldb這個驅動,但是好巧不巧,這個驅動,只支援python2.x版本的,但是現在基本大部分在使用3.x的所以,我們就安裝了PyMySQL這個驅動;

pip install PyMySQL

2. 在Django的工程同名子目錄的__init__.py檔案中新增如下語句 :
將PyMySQL轉為pymysql,作用是讓Django的ORM能以mysqldb的方式來呼叫PyMySQL。

from pymysql import install_as_MySQLdb
install_as_MySQLdb()

3. 修改database

Django中預設使用的資料庫是sqlite
在這裡插入圖片描述

改為:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',  # 資料庫主機
        'PORT': 3306,  # 資料庫埠號
        'USER': ' username ',  # 資料庫使用者名稱
        'PASSWORD': 'password ',  # 資料庫使用者密碼
        'NAME': 'djangotest'  # 資料庫名字
    }
}

在mysql中建立資料庫:

create database djangotest default charset=utf8;

㈢模型類定義:

  • 模型類被定義在"應用/models.py"檔案中。
  • 模型類必須繼承自Model類,位於包django.db.models中。

在子應用/models.py中定義一個模型類如下:

# 定義一個演員類
class Actor(models.Model):
    GENDER_CHOICES = (
        (0, 'male'),
        (1, 'female')
    )
    name = models.CharField(max_length=20, verbose_name='名稱') 
    gender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性別')  
    comment = models.CharField(max_length=200, null=True, verbose_name='描述資訊') 
    book = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='圖書')  # 外來鍵
    is_delete = models.BooleanField(default=False, verbose_name='邏輯刪除')

    class Meta:
        db_table = 'tb_heros'  # 定義資料庫表名
        verbose_name = '演員'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

1) 資料庫表名

模型類如果未指明表名,Django預設以 小寫app應用名_小寫模型類名 為資料庫表名。

可通過db_table 指明資料庫表名。

2) 關於主鍵

django會為表建立自動增長的主鍵列,每個模型只能有一個主鍵列,如果使用選項設定某屬性為主鍵列後django不會再建立自動增長的主鍵列。

預設建立的主鍵列屬性為id,可以使用pk代替,pk全拼為primary key

3) 屬性命名限制

  • 不能是python的保留關鍵字。
  • 不允許使用連續的下劃線,這是由django的查詢方式決定的。
  • 定義屬性時需要指定欄位型別,通過欄位型別的引數指定選項,語法如下:屬性=models.欄位型別(選項)

4)欄位型別
在這裡插入圖片描述

5) 選項
null是資料庫範疇的概念,blank是表單驗證範疇的
在這裡插入圖片描述

6) 外來鍵

在設定外來鍵時,需要通過on_delete選項指明主表刪除資料時,對於外來鍵引用表資料如何處理,在django.db.models中包含了可選常量:

  • CASCADE 級聯,刪除主表資料時連通一起刪除外來鍵表中資料;
  • PROTECT 保護,通過丟擲ProtectedError異常,來阻止刪除主表中被外來鍵應用的資料;
  • SET_NULL 設定為NULL,僅在該欄位null=True允許為null時可用
  • SET_DEFAULT 設定為預設值,僅在該欄位設定了預設值時可用
  • DO_NOTHING 不做任何操作,如果資料庫前置指明級聯性,此選項會丟擲IntegrityError異常;
  • SET() 設定為特定值或者呼叫特定方法如下圖

在這裡插入圖片描述

模型類定義之後,進行資料庫遷移,就會在資料庫中生成對應的資料表:

python manage.py makemigration
python manage.py migrate

㈣資料庫的增刪改查:

先定義兩個模型類:
在這裡插入圖片描述
在這裡插入圖片描述

1.增加

1)save():先建立模型類物件,執行物件的save()方法儲存到資料庫中;

在這裡插入圖片描述

2)create:通過模型類.objects.create()儲存
在這裡插入圖片描述

2.查詢

2.1基本查詢:

  • get 查詢單一結果,如果不存在會丟擲模型類.DoesNotExist異常。
  • all 查詢多個結果。
  • count 查詢結果數量。
    在這裡插入圖片描述

2.2過濾查詢:
實現SQL中的where功能,包括

  • filter 過濾出多個結果
  • exclude 排除掉符合條件剩下的結果
  • get 過濾單一結果

對於過濾條件的使用,上述三個方法相同,故僅以filter進行講解。

過濾條件的表達語法如下:

屬性名稱__比較運算子=值
屬性名稱和比較運算子間使用兩個下劃線,所以屬性名不能包括多個下劃線

exact:表示判等
contains:是否包含
startswith、endswith:以指定值開頭或結尾。
isnull:是否為null。
in:是否包含在範圍內。
gt 大於 (greater then)
gte 大於等於 (greater then equal)
lt 小於 (less then)
lte 小於等於 (less then equal)
不等於的運算子,使用exclude()過濾器。
year、month、day、week_day、hour、minute、second:對日期時間型別的屬性進行運算。

比如:

Movie.objects.filter(id__in=[1, 3, 5])

2.3:F物件
兩個屬性之間的比較:使用F物件,被定義在django.db.models中。
比如:查詢閱讀量大於等於評論量的電影。
在這裡插入圖片描述

2.4:Q物件
多個過濾器逐個呼叫表示邏輯與關係,同sql語句中where部分的and關鍵字。
Q物件可以使用&、|連線,&表示邏輯與,|表示邏輯或。
Q物件前可以使用~操作符,表示非not。

比如:查詢觀看量大於20,或編號小於3的電影,只能使用Q物件實現

Movie.objects.filter(Q(watch__gt=20) | Q(pk__lt=3))

在這裡插入圖片描述

比如:查詢編號不等於3的電影:

Movie.objects.filter(~Q(pk=3))

在這裡插入圖片描述

2.5:排序:order_by

Movie.objects.all().order_by('bread')  # 升序
Movie.objects.all().order_by('-bread')  # 降序

2.5:關聯查詢:

本文案例中,假設電影Movie是一,演員Actor是多;

1)一對多訪問語法:一對應的模型類物件.多對應的模型類名小寫_set
比如:查詢電影對應的演員:

b = Movie.objects.get(id=1)
b.actor_set.all()

2)多對一的訪問語法:多對應的模型類物件.多對應的模型類中的關係類屬性名
比如:查詢某個演員對應是哪個電影

h = Actor.objects.get(id=1)
h.book  # 獲取電影movie物件
h.book_id  #獲取電影movie物件的id

修改

1)save() :修改模型類物件的屬性,然後執行save()方法;
在這裡插入圖片描述

2)update() :使用模型類.objects.filter().update(),會返回受影響的行數
在這裡插入圖片描述

刪除

1)模型類物件delete

actor= Actor.objects.get(id=13)
actor.delete()

2)模型類.objects.filter().delete()

Actor.objects.filter(id=14).delete()

㈤查詢集QuerySet:

1.查詢集概念

Django的ORM中存在查詢集的概念。

查詢集,也稱查詢結果集、QuerySet,表示從資料庫中獲取的物件集合。

當呼叫如下過濾器方法時,Django會返回查詢集(而不是簡單的列表):

  • all():返回所有資料。
  • filter():返回滿足條件的資料。
  • exclude():返回滿足條件之外的資料。
  • order_by():對結果進行排序。

從SQL的角度講,查詢集與select語句等價,過濾器像where、limit、order by子句。

判斷某一個查詢集中是否有資料:

exists():判斷查詢集中是否有資料,如果有則返回True,沒有則返回False。

2.查詢集特性

1)惰性執行
建立查詢集不會訪問資料庫,直到呼叫資料時,才會訪問資料庫,呼叫資料的情況包括迭代、序列化、與if合用;

例如,當執行如下語句時,並未進行資料庫查詢,只是建立了一個查詢集qs:

qs = Movie.objects.all()

繼續執行遍歷迭代操作後,才真正的進行了資料庫的查詢

for actor in qs:
    print(actor .btitle)

2)快取
使用同一個查詢集,第一次使用時會發生資料庫的查詢,然後Django會把結果快取下來,再次使用這個查詢集時會使用快取的資料,減少了資料庫的查詢次數。

3.限制查詢集

可以對查詢集進行取下標或切片操作,等同於sql中的limit和offset子句。

注意:不支援負數索引

對查詢集進行切片後返回一個新的查詢集,不會立即執行查詢。

如果獲取一個物件,直接使用[0],等同於[0:1].get(),但是如果沒有資料,[0]引發IndexError異常,[0:1].get()如果沒有資料引發DoesNotExist異常。

示例:獲取第1、2項,執行檢視。

qs = Actor.objects.all()[0:2]

在這裡插入圖片描述

㈥自定義管理器Manager:

管理器是Django的模型進行資料庫操作的介面,Django應用的每個模型類都擁有至少一個管理器。

我們在通過模型類的objects屬性提供的方法操作資料庫時,即是在使用一個管理器物件objects。當沒有為模型類定義管理器時,Django會為每一個模型類生成一個名為objects的管理器,它是models.Manager類的物件。

注意:一旦為模型類指明自定義的過濾器後,Django不再生成預設管理物件objects

1. 修改原始查詢集,重寫all()方法。
在這裡插入圖片描述
2. 在管理器類中補充定義新的方法
在這裡插入圖片描述