一、理解Django的makemigrations
和migrate
因为前面多次因为makemigrations
命令报错,我们来系统的理解一下Django的makemigrations
和migrate
命令。
在你改动了 model.py的内容之后执行下面的命令:
python manger.py makemigrations
相当于在该app下建立 migrations
目录,并记录下你所有的关于modes.py
的改动,比如0001_initial.py
, 但是这个改动还没有作用到数据库文件。
你可以手动打开这个文件,看看里面是什么。当makemigrations
之后产生了0001_initial.py
文件,你可以查看下该migrations
会对应于什么样子的SQL命令,使用如下命令,
python manger.py sqlmigrate theapp 0001
看到的大概是这样子的:
BEGIN;
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
COMMIT;
在makemigrations
之后执行命令:
python manager.py migrate
将该改动作用到数据库文件,比如产生table,修改字段的类型等。
二、报错
在做完数据库设计后,在models.py中建表,然后执行makemigrations
命令在app下建立 migrations
目录。
错误1:No module named ‘markdown’
ModuleNotFoundError: No module named 'markdown'
原因:缺乏markdown模块
实际上,这个错误有点懵,我明明在PyCharm中已经下载了markdown模块,如下:
解决方案:
尝试在虚拟环境中安装markdown模块:
(fswy) blog xiatian$ pip3 install markdown
Collecting markdown
......
Successfully installed markdown-3.2.1
难道这两块是分开的???
暂时不管吧。
重现输入:$ python3 manage.py makemigrations
错误2:required positional argument: ‘on_delete’
bigcategory = models.ForeignKey(BigCategory, verbose_name='大分类')
TypeError: __init__() missing 1 required positional argument: 'on_delete'
原因:
django 升级到2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常。
解决方案:
定义外键的时候需要加上 on_delete=
即:
contract = models.ForeignKey(Contract, on_delete=models.CASCADE)
on_delete各个参数的含义如下:
on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE, # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError
# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET, # 删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
注意:
由于多对多(ManyToManyField)没有 on_delete 参数,所以以上只针对外键(ForeignKey)和一对一(OneToOneField)。
重现输入:$ python3 manage.py makemigrations
错误3:AUTH_USER_MODEL must be of the form ‘app_label.model_name’
raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL must be of the form 'app_label.model_name'
原因:
在settings.py中,AUTH_USER_MODEL=" "
,但它必须是'app_label.model_name'
类型
解决方案:
在settings.py中
# 作者(网站注册用户)
AUTH_USER_MODEL = 'user.Ouser'
重现输入:$ python3 manage.py makemigrations
(fswy) blog xiatian$ python3 manage.py makemigrations
Migrations for 'fswy':
fswy/migrations/0002_activate_article_bigcategory_carousel_category_friendlink_keyword_tag.py
- Create model Activate
- Create model Article
- Create model BigCategory
- Create model Carousel
- Create model FriendLink
- Create model Keyword
- Create model Tag
- Create model Category
fswy/migrations/0003_auto_20200424_1819.py
- Add field author to article
- Add field category to article
- Add field keywords to article
- Add field tags to article
Migrations for 'user':
user/migrations/0001_initial.py
- Create model Ouser
终于成功了,执行migrate
命令。
(fswy) blog xiatian$ python3 manage.py migrate
错误4:
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency user.0001_initial on database 'default'.
原因:
如果我们一开始使用的是django原生模型User,在后来的开发中,我们在其他app中想使用自己的User模型,在我们makemigrations
时,就会出现以上错误。
解决方法:
一:
- 删除除了auth_user表以外的所有数据库
- 删除与用户有关app下的migrations文件夹
- 重新makemigrations + migrate
缺点:这个方法相当于从头到尾更新重建了我们的数据模型,需要我们备份数据库中的数据
二:
- 在setttings文件中注释掉:django.contrib.admin
- 在urls文件中注释掉:path(‘admin/’, admin.site.urls)
- 重新migrate
- 将刚才注释的代码加回去
- 重新migrate
这里采取方法二
(fswy)blog xiatian$ python3 manage.py migrate
Operations to perform:
Apply all migrations: auth, contenttypes, fswy, sessions, user
Running migrations:
Applying user.0001_initial... OK
Applying fswy.0002_activate_article_bigcategory_carousel_category_friendlink_keyword_tag... OK
Applying fswy.0003_auto_20200424_1819... OK
(fswy)blog xiatian$ python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, fswy, sessions, user
Running migrations:
No migrations to apply.
在PyCharm中打开Database,刷新,可以看到如图所示:
即已经将新建的这些表添加到我们的数据库 blog 中了。
转载:https://blog.csdn.net/yxys01/article/details/105738705