上一篇章講述瞭如何建立項目,本篇章主要講解Django的模型設計。python
Django 官網 2.1 文檔mysql
通常操做數據庫是經過寫sql語句,那麼能不能不寫sql語句就能夠操做數據庫呢? 能夠,就是經過接下來要給你們講的ORM框架。redis
本篇章首先使用Django默認使用的sqlite3,後續再繼續講解使用mysql。sql
O是object,也就類對象的意思,R是relation,翻譯成中文是關係,也就是關係數據庫中數據表的意思,M是mapping,是映射的意思。在ORM框架中,它幫咱們把類和數據表進行了一個映射,可讓咱們經過類和類對象就能操做它所對應的表格中的數據。ORM框架還有一個功能,它能夠根據咱們設計的類自動幫咱們生成數據庫中的表格,省去了咱們本身建表的過程。shell
django中內嵌了ORM框架,不須要直接面向數據庫編程,而是定義模型類,經過模型類和對象完成數據表的增刪改查操做。數據庫
使用django進行數據庫開發的步驟以下:django
下面咱們以保存服務器資產信息爲例來給你們介紹Django中進行數據庫開發的整個流程。編程
模型類定義在models.py文件中,繼承自models.Model類。bash
說明:不須要定義主鍵列,在生成時會自動添加,而且值爲自動增加。服務器
服務器類:
根據設計,在models.py中定義模型類以下:
from django.db import models
class ServerInfo(models.Model):
server_hostname = models.CharField(max_length=20, default=None)
server_intranet_ip = models.CharField(max_length=20,default=None)
server_internet_ip = models.CharField(max_length=20,default=None)
server_shelves_date = models.DateField(auto_now_add=True)
複製代碼
下一步就可使用Django自帶的遷移的方式,建立數據庫表。
上面的一小段用於建立模型的代碼給了 Django 不少信息,經過這些信息,Django 能夠:
爲了在咱們的工程中包含這個應用,咱們須要在配置類 INSTALLED_APPS
中添加設置。由於 AssetinfoConfig
類寫在文件 assetinfo/apps.py
中,因此它的點式路徑是 'assetinfo.apps.AssetinfoConfig'
。在文件 mysite/settings.py
中 INSTALLED_APPS
子項添加點式路徑後,它看起來像這樣:
不用死記硬背這個點路徑,pycharm會自動提示。
如今你的 Django 項目會包含 assetinfo 應用。接着運行下面的命令:
$ python3 manage.py makemigrations assetinfo
看看生成的這個文件是什麼樣的,以下:
Django框架根據咱們設計的模型類生成了遷移文件,在遷移文件中咱們能夠看到fields列表中每個元素跟Serverinfo類屬性名以及屬性的類型是一致的。同時咱們發現多了一個id項,這一項是Django框架幫咱們自動生成的,在建立表的時候id就會做爲對應表的主鍵列,而且主鍵列自動增加。
執行遷移命令以下: python3 manage.py migrate
當執行遷移命令後,Django框架會讀取遷移文件自動幫咱們在數據庫中生成對應的表格。
遷移後目錄結構以下圖:
Django默認採用sqlite3數據庫,上圖中的db.sqlite3就是Django框架幫咱們自動生成的數據庫文件。 sqlite3是一個很小的數據庫,一般用在手機中,它跟mysql同樣,咱們也能夠經過sql語句來操做它。
從上圖能夠看到自動建立生成的表以及字段。
細心的讀者會發現上面生成的表的名字叫作assetinfo_serverinfo,assetinfo是應用的名字,serverinfo是模型類的名字。
數據表的默認名稱爲:
<app_name>_<model_name>
例:
assetinfo_serverinfo
複製代碼
中間件類:
類名:MiddlewareInfo 中間件名稱:name 中間件端口號:port 中間件所屬服務器:server 服務器-中間件的關係爲一對多
打開assetinfo/models.py,定義中間件類代碼以下:
# 中間件類:MiddlewareInfo
# 中間件名稱: name
# 中間件端口號:port
# 中間件所屬服務器:server
class MiddlewareInfo(models.Model):
name = models.CharField(max_length=20)
port = models.IntegerField()
server = models.ForeignKey('ServerInfo')
複製代碼
這裏要說明的是,ServerInfo類和MiddlewareInfo類之間具備一對多的關係,這個一對多的關係應該定義在多的那個類,也就是MiddlewareInfo類中。
server = models.ForeignKey('ServerInfo')這句代碼就讓ServerInfo類和MiddlewareInfo類之間創建了一對多的關係。
在咱們以後遷移生成表的時候,Django框架就會自動幫咱們在圖書表和英雄表之間創建一個外鍵關係。
生成遷移文件: python3 manage.py makemigrations assetinfo
執行以後,能夠發現錯誤以下:
那麼怎麼解決這個錯誤呢?
在外鍵值的後面加上 on_delete=models.CASCADE
能夠看到錯誤提示,還須要設置一個默認值,那麼下面就寫多一個默認值,以下:
能夠看到執行成功了。
中間類的代碼以下:
class MiddlewareInfo(models.Model):
name = models.CharField(max_length=20)
port = models.IntegerField()
server = models.ForeignKey('ServerInfo',on_delete=models.CASCADE, default=None)
複製代碼
再查看一下生成的遷移文件,以下:
python3 manage.py migrate
注意上圖中assetinfo_middlewareinfo表中有一列server_id,這一列名爲何不叫server? server_id是根據MiddlewareInfo類的關係屬性server生成的,對應着服務器表中的主鍵id。
完成數據表的遷移以後,下面就能夠經過進入項目的shell,進行簡單的API操做。
進入項目shell的命令: python3 manage.py shell
由於我安裝了ipython3,因此會自動進入ipython3的工具。
首先引入assetinfo/models中的類: from assetinfo.models import ServerInfo,MiddlewareInfo
查詢全部服務器信息:
In [3]: ServerInfo.objects.all()
Out[3]: <QuerySet []>
複製代碼
由於當前並無數據,因此返回空查詢結果集。
新建服務器信息對象並寫入一條數據:
In [7]: s = ServerInfo()
In [8]: s
Out[8]: <ServerInfo: ServerInfo object (None)>
In [9]: s.server_hostname = "test_server"
In [10]: s.server_intranet_ip = "172.168.0.1"
In [11]: s.server_internet_ip = "223.5.5.5"
In [12]: from datetime import date
In [13]: s.server_shelves_date = date(2019,6,4)
In [14]: s.save()
In [15]:
複製代碼
再次查詢全部服務器信息:
In [15]: ServerInfo.objects.all()
Out[15]: <QuerySet [<ServerInfo: ServerInfo object (1)>]>
In [16]:
複製代碼
In [16]: server_info = ServerInfo.objects.get( id = 1 )
In [17]: server_info
Out[17]: <ServerInfo: ServerInfo object (1)>
In [18]: server_info.id
Out[18]: 1
In [19]: server_info.server_hostname
Out[19]: 'test_server'
In [20]: server_info.server_shelves_date
Out[20]: datetime.date(2019, 6, 4)
In [21]: server_info.server_intranet_ip
Out[21]: '172.168.0.1'
In [22]: server_info.server_internet_ip
Out[22]: '223.5.5.5'
複製代碼
In [23]: server_info.server_shelves_date = date(2018,6,4)
In [24]: server_info.save()
In [26]: server_info.server_shelves_date
Out[26]: datetime.date(2018, 6, 4)
In [27]:
複製代碼
從navicat查看以下:
server_info.delete()
In [27]: server_info.delete()
Out[27]: (1, {'assetinfo.MiddlewareInfo': 0, 'assetinfo.ServerInfo': 1})
In [28]: ServerInfo.objects.all()
Out[28]: <QuerySet []>
In [29]:
複製代碼
建立一個ServerInfo對象,寫入一條服務器信息:
In [29]: server1 = ServerInfo()
In [30]: server1.server_hostname = "redis_server"
In [32]: server1.server_intranet_ip = "172.168.0.1"
In [33]: server1.server_internet_ip = "223.5.5.5"
In [35]: server1.server_shelves_date = date(2019,6,4)
In [36]: server1.save()
複製代碼
建立一個MiddlewareInfo對象,寫入兩條中間件信息:
In [39]: m1 = MiddlewareInfo()
In [40]: m1.name = "redis"
In [41]: m1.port = 6379
In [42]: m1.server = server1
In [43]: m1.save()
In [44]: m2 = MiddlewareInfo()
In [45]: m2.name = "memcached"
In [46]: m2.port = "26379"
In [47]: m2.server = server1
In [48]: m2.save()
In [49]: MiddlewareInfo.objects.all()
Out[49]: <QuerySet [<MiddlewareInfo: MiddlewareInfo object (1)>, <MiddlewareInfo: MiddlewareInfo object (2)>]>
複製代碼
服務器與中間件是一對多的關係,django中提供了關聯的操做方式。
得到關聯集合:返回當前server1對象的全部中間件。
In [50]: server1.middlewareinfo_set.all()
Out[50]: <QuerySet [<MiddlewareInfo: MiddlewareInfo object (1)>, <MiddlewareInfo: MiddlewareInfo object (2)>]>
In [51]:
複製代碼