1. 設計模型
我們之前操作數據庫是通過寫sql語句,那么能不能不寫sql語句就可以操作數據庫呢? 當然可以,這就要使用ORM框架了。
1.1 ORM框架
O是object,也就類對象的意思,R是relation,翻譯成中文是關系,也就是關系數據庫中數據表的意思,M是mapping,是映射的意思。在ORM框架中,它幫我們把類和數據表進行了一個映射,可以讓我們通過類和類對象就能操作它所對應的表格中的數據。ORM框架還有一個功能,它可以根據我們設計的類自動幫我們生成數據庫中的表格,省去了我們自己建表的過程。
django中內嵌了ORM框架,不需要直接面向數據庫編程,而是定義模型類,通過模型類和對象完成數據表的增刪改查操作。
使用django進行數據庫開發有三個步驟:
1.在models.py中定義模型類
2.遷移
3.通過類和對象完成數據增刪改查操作
下面我們就以保存圖書信息為例來給大家介紹Django中進行數據庫開發的整個流程。
1.2 創建模型
在booktest下的models.py中創建模型,需要繼承models.Model類:
from django.db import models #設計和表對應的類 模型類 # Create your models here. #圖書類 class BookInfo(models.Model): '''圖書模型類''' #圖書名稱 CharField說明是一個字符串 max_length指定字符串的最大長度 btitle = models.CharField(max_length=20) #出版日期 DateField說明是一個日期類型 bpub_date = models.DateField()
1.3 遷移
遷移有兩步:
1.生成遷移文件:根據模型類生成創建表的遷移文件。
2.執行遷移:根據第一步生成的遷移文件在數據庫中創建表。
生成遷移文件命令如下:
python manage.py makemigrations

執行生成遷移文件命令后,會在應用booktest目錄下的migrations目錄中生成遷移文件。

我們打開這個文件,內容如下:
# Generated by Django 3.0.2 on 2020-01-15 07:01 from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='BookInfo', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('btitle', models.CharField(max_length=20)), ('bpub_date', models.DateField()), ], ), ]
Django框架根據我們設計的模型類生成了遷移文件,在遷移文件中我們可以看到fields列表中每一個元素跟BookInfo類屬性名以及屬性的類型是一致的。同時我們發現多了一個id項,這一項是Django框架幫我們自動生成的,在創建表的時候id就會作為對應表的主鍵列,並且主鍵列自動增長。

當執行遷移命令后,Django框架會讀取遷移文件自動幫我們在數據庫中生成對應的表格。
 
Django默認采用sqlite3數據庫,上圖中的db.sqlite3就是Django框架幫我們自動生成的數據庫文件。 sqlite3是一個很小的數據庫,通常用在手機中,它跟mysql一樣,我們也可以通過sql語句來操作它。
但是我們一般是使用mysql作為案例的,所以我們需要將模型轉為mysql數據庫中的表。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'bms', # 要連接的數據庫,連接前需要創建好 'USER':'root', # 連接數據庫的用戶名 'PASSWORD':'root', # 連接數據庫的密碼 'HOST':'127.0.0.1', # 連接主機,默認本機 'PORT':3306 # 端口 默認3306 } }
NAME即數據庫的名字,在mysql連接前該數據庫必須已經創建,而上面的sqlite數據庫下的db.sqlite3則是項目自動創建 USER和PASSWORD分別是數據庫的用戶名和密碼。設置完后,再啟動我們的Django項目前,我們需要激活我們的mysql。然后,啟動項目,會報錯:no module named MySQLdb 。這是因為django默認你導入的驅動是MySQLdb,可是MySQLdb對於py3有很大問題,所以我們需要的驅動是PyMySQL。所以我們還需要找到項目名下的__init__,在里面寫入:
import pymysql pymysql.install_as_MySQLdb()
然后我們還要注意一個報錯,報錯如下:
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
MySQLclient目前只支持到python3.4,因此如果使用的更高版本的python,需要修改如下:
通過路徑查找E:\pythondaima\venv\Lib\site-packages\django\db\backends\mysql\base..py。在這個路徑下找到如下地方:

注釋掉就OK了。
還有就是上一章講過的,確保配置文件中的INSTALLED_APPS中寫入我們創建的app名稱。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'booktest', ]
刪除原來生成的文件,重新運行兩條命令:
python manage.py makemigrations
python manage.py migrate

我們可以看到生成的表名叫做booktest_bookinfo,booktest是應用的名字,bookinfo是模型類的名字。
我們再弄個角色類:
在booktest/models.py,定義角色類:
class RoleInfo(models.Model): '''角色人物模型類''' # 角色名 rname = models.CharField(max_length=20) # 性別 rgender = models.BooleanField() # 備注 rcomment = models.CharField(max_length=100) # 關系屬性 rbook = models.ForeignKey('BookInfo',on_delete=models.CASCADE)
在外鍵值的后面加上 on_delete=models.CASCADE,因為在django2.0后,定義外鍵和一對一關系的時候需要加on_delete選項,此參數為了避免兩個表里的數據不一致問題,不然會報錯。

這里要說明的是,BookInfo類和RoleInfo類之間具有一對多的關系,這個一對多的關系應該定義在多的那個類,也就是RoleInfo類中。
在我們之后遷移生成表的時候,Django框架就會自動幫我們在圖書表和角色表之間建立一個外鍵關系。
python manage.py makemigrations
python manage.py migrate

1.4 操作數據庫
1.4.1 單表操作
完成數據表的遷移之后,下面就可以通過進入項目的shell,進行簡單的API操作。如果需要退出項目,可以使用ctrl+d快捷鍵或輸入quit()。
進入項目shell的命令:
python manage.py shell

首先引入booktest/models中的類:
from booktest.models import BookInfo,RoleInfo
查詢所有圖書信息:
BookInfo.objects.all()
因為當前並沒有數據,所以返回空列表。

新建圖書對象:
b=BookInfo() b.btitle="斗羅大陸" from datetime import date b.bpub_date=date(2008,12,14) b.save()

再次查詢所有圖書信息:
BookInfo.objects.all()

查找圖書信息並查看值:
b=BookInfo.objects.get(id=1)
b
b.id
b.btitle
b.bpub_date 
        
修改圖書信息:
b.bpub_date=date(2017,1,1)
b.save()
b.bpub_date 
        
刪除圖書信息:
b.delete()

1.4.2 多表關聯操作
對於RoleInfo可以按照上面的方式進行增刪改查操作。
創建一個BookInfo對象
b=BookInfo() b.btitle='abc' b.bpub_date=date(2017,1,1) b.save()
創建一個RoleInfo對象
r=RoleInfo() r.rname='a1' r.rgender=False r.rcomment='he is a boy' r.rbook=b r.save()
圖書與角色是一對多的關系,django中提供了關聯的操作方式。
獲得關聯集合:返回當前book對象的所有role。
b.roleinfo_set.all()

