Django2.0-db(12)-根據已有的表自動生成模型
阿新 • • 發佈:2019-02-18
根據已有的表自動生成模型:
在實際開發中,有些時候可能資料庫已經存在了。如果我們用Django
來開發一個網站,讀取的是之前已經存在的資料庫中的資料。那麼該如何將模型與資料庫中的表對映呢?根據舊的資料庫生成對應的ORM
模型,需要以下幾個步驟:
-
Django
給我們提供了一個inspectdb
的命令,可以非常方便的將已經存在的表,自動的生成模型。想要使用inspectdb
自動將表生成模型。首先需要在settings.py
中配置好資料庫相關資訊。不然就找不到資料庫。示例程式碼如下:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql'
那麼通過
python manage.py inspectdb
,就會將錶轉換為模型後的程式碼,顯示在終端
如果想要儲存到檔案中。那麼可以使用>
重定向輸出到指定的檔案。比如讓他輸出到models.py
檔案中。
python manage.py inspectdb > models. py
以上的命令,只能在終端執行,不能在pycharm中Tools->Run manage.py Task...
中使用。
如果只是想要轉換一個表為模型。那麼可以指定表的名字。示例命令如下:
python manage.py inspectdb article_article > models.py
-
修正模型:新生成的
ORM
模型有些地方可能不太適合使用。比如模型的名字,表之間的關係等等。那麼以下選項還需要重新配置一下:- 模型名(類名):自動生成的模型,是根據表的名字生成的,可能不是你想要的。這時候模型的名字你可以改成任何你想要的。
- 模型所屬app:根據自己的需要,將相應的模型放在對應的app中。
- 模型外來鍵引用:將所有使用
ForeignKey
的地方,模型引用都改成字串。這樣不會產生模型順序的問題。另外,如果引用的模型已經移動到其他的app中了,那麼還要加上這個app的字首。 - 讓Django管理模型:將
Meta
下的managed=False
刪掉,如果保留這個,那麼以後這個模型有任何的修改,使用migrate
都不會對映到資料庫中。
當有多對多的時候,應該也要修正模型。將中間表註釋,然後使用ManyToManyField
來實現多對多。並且,使用ManyToManyField
生成的中間表的名字可能和資料庫中那個中間表的名字不一致,這時候肯定就不能正常連線了。那麼可以通過db_table
來指定中間表的名字。示例程式碼如下:
class Article(models.Model):
title = models.CharField(max_length=100, blank=True, null=True)
content = models.TextField(blank=True, null=True)
author = models.ForeignKey('front.User', models.SET_NULL, blank=True, null=True)
# 使用ManyToManyField模型到表,生成的中間表的規則是:article_tags
# 但現在已經存在的表的名字叫做:article_tag
# 可以使用db_table,指定中間表的名字
tags = models.ManyToManyField("Tag",db_table='article_tag')
class Meta:
db_table = 'article'
- 表名:切記不要修改表的名字。不然對映到資料庫中,會發生找不到對應表的錯誤。
- 執行命令
python manage.py makemigrations
生成初始化的遷移指令碼。方便後面通過ORM
來管理表。這時候還需要執行命令python manage.py migrate --fake-initial
,因為如果不使用--fake-initial
,那麼會將遷移指令碼會對映到資料庫中。這時候遷移指令碼會新建立表,而這個表之前是已經存在了的,所以肯定會報錯。此時我們只要將這個0001-initial
的狀態修改為已經對映,而不真正執行對映,下次再migrate
的時候,就會忽略他。 - 將
Django
的核心表對映到資料庫中:Django
中還有一些核心的表也是需要建立的。不然有些功能是用不了的。比如auth
相關表。如果這個資料庫之前就是使用Django
開發的,那麼這些表就已經存在了。可以不用管了。如果之前這個資料庫不是使用Django
開發的,那麼應該使用migrate
命令將Django
中的核心模型對映到資料庫中,使用python manage.py migrate [AppName]