[英]How to change the name of a Django app?
I have changed the name of an app in Django by renaming its folder, imports and all its references (templates/indexes).我通过重命名其文件夹、导入及其所有引用(模板/索引)来更改 Django 中应用程序的名称。 But now I get this error when I try to run python manage.py runserver
但是现在当我尝试运行python manage.py runserver
时出现此错误
Error: Could not import settings 'nameofmynewapp.settings' (Is it on sys.path?): No module named settings
How can I debug and solve this error?我该如何调试和解决这个错误? Any clues?有什么线索吗?
Follow these steps to change an app's name in Django:按照以下步骤在 Django 中更改应用程序的名称:
views.py
, urls.py
, 'manage.py' , and settings.py
files.在它们的依赖项中更改对您的应用程序的任何引用,即应用程序的views.py
、 urls.py
、 'manage.py' 和settings.py
文件。django_content_type
with the following command: UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>'
使用以下命令编辑数据库表django_content_type
: UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>'
ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName
.对于 postgres 使用ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName
。 For mysql too I think it is the same (as mentioned by @null_radix)对于 mysql,我也认为它是相同的(如@null_radix 所述)django_migrations
table to avoid having your previous migrations re-run: UPDATE django_migrations SET app='<NewAppName>' WHERE app='<OldAppName>'
. (对于 Django >= 1.7)更新django_migrations
表以避免重新运行之前的迁移: UPDATE django_migrations SET app='<NewAppName>' WHERE app='<OldAppName>'
。 Note : there is some debate (in comments) if this step is required for Django 1.8+;注意:如果 Django 1.8+ 需要此步骤,则存在一些争论(在评论中); If someone knows for sure please update here.如果有人确定,请在此处更新。models.py
's Meta Class has app_name
listed, make sure to rename that too (mentioned by @will).如果您的models.py
的 Meta Class 列出了app_name
,请确保也将其重命名(@will 提到)。static
or templates
folders inside your app, you'll also need to rename those.如果您已在应用程序中为static
或templates
文件夹命名,则还需要重命名它们。 For example, rename old_app/static/old_app
to new_app/static/new_app
.例如,将old_app/static/old_app
重命名为new_app/static/new_app
。models
, you'll need to change django_content_type.name
entry in DB.要重命名 django models
,您需要更改数据库中的django_content_type.name
条目。 For postgreSQL use UPDATE django_content_type SET name='<newModelName>' where name='<oldModelName>' AND app_label='<OldAppName>'
对于 postgreSQL 使用UPDATE django_content_type SET name='<newModelName>' where name='<oldModelName>' AND app_label='<OldAppName>'
__pycache__/
folder inside the app must be removed, otherwise you get EOFError: marshal data too short when trying to run the server
. 2021 年 7 月 16日更新:此外,必须删除应用程序内的__pycache__/
文件夹,否则EOFError: marshal data too short when trying to run the server
会出现EOFError: marshal data too short when trying to run the server
。 Mentioned by @Serhii Kushchenko由@Serhii Kushchenko 提及Meta point (If using virtualenv): Worth noting, if you are renaming the directory that contains your virtualenv, there will likely be several files in your env that contain an absolute path and will also need to be updated.元点(如果使用 virtualenv):值得注意的是,如果您正在重命名包含您的 virtualenv 的目录,您的 env 中可能会有几个包含绝对路径的文件,并且也需要更新。 If you are getting errors such as ImportError: No module named ...
this might be the culprit.如果您收到诸如ImportError: No module named ...
类的ImportError: No module named ...
这可能是罪魁祸首。 (thanks to @danyamachine for providing this). (感谢@danyamachine 提供此信息)。
Other references: you might also want to refer the below links for a more complete picture其他参考:您可能还想参考以下链接以获得更完整的图片
New in Django 1.7 is a app registry that stores configuration and provides introspection. Django 1.7 中的新功能是一个应用程序注册表,用于存储配置并提供自省。 This machinery let's you change several app attributes.这个机器让你改变几个应用程序属性。
The main point I want to make is that renaming an app isn't always necessary: With app configuration it is possible to resolve conflicting apps.我想说的主要观点是重命名应用程序并不总是必要的:通过应用程序配置可以解决冲突的应用程序。 But also the way to go if your app needs friendly naming.但如果您的应用程序需要友好命名,这也是可行的方法。
As an example I want to name my polls app 'Feedback from users'.例如,我想将我的投票应用程序命名为“来自用户的反馈”。 It goes like this:它是这样的:
Create a apps.py
file in the polls
directory:在polls
目录中创建一个apps.py
文件:
from django.apps import AppConfig
class PollsConfig(AppConfig):
name = 'polls'
verbose_name = "Feedback from users"
Add the default app config to your polls/__init__.py
:将默认应用配置添加到您的polls/__init__.py
:
default_app_config = 'polls.apps.PollsConfig'
For more app configuration: https://docs.djangoproject.com/en/1.7/ref/applications/更多应用配置: https : //docs.djangoproject.com/en/1.7/ref/applications/
Fun problem!有趣的问题! I'm going to have to rename a lot of apps soon, so I did a dry run.很快我将不得不重命名很多应用程序,所以我做了一次试运行。
This method allows progress to be made in atomic steps, to minimise disruption for other developers working on the app you're renaming.此方法允许在原子步骤中取得进展,以尽量减少对正在重命名的应用程序上工作的其他开发人员的干扰。
See the link at the bottom of this answer for working example code.有关工作示例代码,请参阅此答案底部的链接。
name
and label
to defaults).创建应用配置(将name
和label
设置为默认值)。INSTALLED_APPS
.将应用程序配置添加到INSTALLED_APPS
。db_table
to the current value.在所有模型上,将db_table
显式设置为当前值。db_table
was "always" explicitly defined.医生迁移以便db_table
被“始终”明确定义。Change the app label :更改应用标签:
label
in app config to new app name.将应用配置中的label
设置为新的应用名称。<app_label>/<model_name>_<suffix>.html
)更新基于类的通用视图的模板( 默认路径是<app_label>/<model_name>_<suffix>.html
) Run raw SQL to fix migrations and content_types
app (unfortunately, some raw SQL is unavoidable).运行原始 SQL 来修复迁移和content_types
应用程序(不幸的是,一些原始 SQL 是不可避免的)。 You can not run this in a migration.您不能在迁移中运行它。
UPDATE django_migrations SET app = 'catalogue' WHERE app = 'shop'; UPDATE django_content_type SET app_label = 'catalogue' WHERE app_label = 'shop';
Ensure no migrations are required (checks previous step).确保不需要迁移(检查上一步)。
db_table
.删除“自定义” db_table
。makemigrations
so django can rename the table "to the default".运行makemigrations
以便 django 可以将表重命名为“默认值”。name
.更新应用配置的name
。INSTALLED_APPS
references the app config.更新INSTALLED_APPS
引用应用程序配置的位置。INSTALLED_APPS
.如果应用程序配置不见了,不要忘记也将其从INSTALLED_APPS
删除。Example solution: I've created app-rename-example , an example project where you can see how I renamed an app, one commit at a time.示例解决方案:我创建了app-rename-example ,这是一个示例项目,您可以在其中查看我如何重命名应用程序,一次提交一次。
The example uses Python 2.7 and Django 1.8, but I'm confident the same process will work on at least Python 3.6 and Django 2.1.该示例使用 Python 2.7 和 Django 1.8,但我相信相同的过程至少适用于 Python 3.6 和 Django 2.1。
In case you are using PyCharm and project stops working after rename:如果您正在使用 PyCharm 并且项目在重命名后停止工作:
In many cases, I believe @allcaps's answer works well.在许多情况下,我相信@allcaps 的回答很有效。
However, sometimes it is necessary to actually rename an app, eg to improve code readability or prevent confusion.但是,有时需要实际重命名应用程序,例如提高代码可读性或防止混淆。
Most of the other answers involve either manual database manipulation or tinkering with existing migrations , which I do not like very much.大多数其他答案涉及手动数据库操作或修补现有的迁移,我不太喜欢这些。
As an alternative, I like to create a new app with the desired name, copy everything over, make sure it works, then remove the original app:作为替代方案,我喜欢创建一个具有所需名称的新应用程序,复制所有内容,确保其正常工作,然后删除原始应用程序:
Start a new app with the desired name, and copy all code from the original app into that.使用所需名称启动一个新应用程序,并将原始应用程序中的所有代码复制到该应用程序中。 Make sure you fix the namespaced stuff, in the newly copied code, to match the new app name.确保在新复制的代码中修复命名空间的内容,以匹配新的应用程序名称。
makemigrations
and migrate
. makemigrations
和migrate
。 Note: if the app has a lot of foreign keys, there will likely be issues with clashing reverse accessors when trying to run the initial migration for the copied app.注意:如果应用程序有很多外键,则在尝试为复制的应用程序运行初始迁移时,可能会出现反向访问器冲突的问题。 You have to rename the related_name accessor (or add new ones) on the old app to resolve the clashes.您必须重命名旧应用程序上的 related_name 访问器(或添加新访问器)以解决冲突。
Create a data migration that copies the relevant data from the original app's tables into the new app's tables, and migrate
again.创建数据迁移,将相关数据从原始应用的表复制到新应用的表中,然后再次migrate
。
At this point, everything still works, because the original app and its data are still in place.此时,一切仍然有效,因为原始应用程序及其数据仍然存在。
Now you can refactor all the dependent code, so it only makes use of the new app.现在你可以重构所有的依赖代码,所以它只使用新的应用程序。 See other answers for examples of what to look out for.有关需要注意的事项的示例,请参阅其他答案。
Once you are certain that everything works, you can remove the original app.一旦确定一切正常,您就可以删除原始应用程序。 This involves another (schema) migration.这涉及另一个(架构)迁移。
This has the advantage that every step uses the normal Django migration mechanism, without manual database manipulation, and we can track everything in source control.这样做的好处是每一步都使用正常的Django迁移机制,无需手动操作数据库,我们可以在源代码控制中跟踪所有内容。 In addition, we keep the original app and its data in place until we are sure everything works.此外,我们会保留原始应用程序及其数据,直到我们确定一切正常。
Re-migrate approach for a cleaner plate.重新迁移方法以获得更清洁的印版。
This can painlessly be done IF other apps do not foreign key models from the app to be renamed.如果其他应用程序没有来自要重命名的应用程序的外键模型,则可以轻松完成此操作。 Check and make sure their migration files don't list any migrations from this one.检查并确保他们的迁移文件没有列出来自这个的任何迁移。
delete from auth_permission where content_type_id in (select id from django_content_type where app_label = '<OldAppName>')
删除权限: delete from auth_permission where content_type_id in (select id from django_content_type where app_label = '<OldAppName>')
delete from django_content_type where app_label = '<OldAppName>'
删除内容类型: delete from django_content_type where app_label = '<OldAppName>'
views.py
, urls.py
, 'manage.py' , and settings.py
files.在它们的依赖项中更改对您的应用程序的任何引用,即应用程序的views.py
、 urls.py
、 'manage.py' 和settings.py
文件。delete from django_migrations where app = '<OldAppName>'
删除迁移: delete from django_migrations where app = '<OldAppName>'
models.py
's Meta Class has app_name
listed, make sure to rename that too (mentioned by @will).如果您的models.py
的 Meta Class 列出了app_name
,请确保也将其重命名(@will 提到)。static
or templates
folders inside your app, you'll also need to rename those.如果您已在应用程序中为static
或templates
文件夹命名,则还需要重命名它们。 For example, rename old_app/static/old_app
to new_app/static/new_app
.例如,将old_app/static/old_app
重命名为new_app/static/new_app
。If you use Pycharm , renaming an app is very easy with refactoring ( Shift
+ F6
default) for all project files.如果您使用Pycharm ,通过重构(默认为Shift
+ F6
)为所有项目文件重命名应用程序非常容易。
But make sure you delete the __pycache__
folders in the project directory & its sub-directories.但请确保删除项目目录及其子目录中的__pycache__
文件夹。 Also be careful as it also renames comments too which you can exclude in the refactor preview window it will show you.还要小心,因为它也会重命名注释,您可以在它会显示的重构预览窗口中排除这些注释。
And you'll have to rename OldNameConfig(AppConfig): in apps.py
of your renamed app in addition.此外,您还必须在重命名的应用程序的apps.py
中重命名 OldNameConfig(AppConfig): 。
If you do not want to lose data of your database, you'll have to manually do it with query in database like the aforementioned answer.如果您不想丢失数据库的数据,则必须像上述答案一样在数据库中使用查询手动执行此操作。
Simple 4 steps to rename an existing app in Django project without any pain or data loss.在 Django 项目中重命名现有应用程序的简单 4 个步骤,没有任何痛苦或数据丢失。
Step 1步骤1
Rename the app folder.重命名应用程序文件夹。 For this example,"old_app" is our old name and "new_app" is our new name".对于本示例,“old_app”是我们的旧名称,“new_app”是我们的新名称”。
mv ./old_app ./new_app
Step 2第2步
Update all imports referencing the old folder to reference the new.更新所有引用旧文件夹的导入以引用新文件夹。
For example:例如:
# Before
from myproject.old_app import models
# After
from myproject.new_app import models
Step 3第 3 步
Update old app name references within the Django migrations .更新Django 迁移中的旧应用名称引用。
Example changes you'll likely have to make:您可能需要进行的更改示例:
# Before
dependencies = [
('old_app', '0023_auto_20200403_1050'),
]
# After
dependencies = [
('new_app', '0023_auto_20200403_1050'),
]
# Before
field = models.ForeignKey(
default=None, on_delete=django.db.models.deletion.CASCADE,
to='old_app.Experiment'
)
# After
field = models.ForeignKey(
default=None, on_delete=django.db.models.deletion.CASCADE,
to='new_app.Experiment'
)
Step 4第四步
Make a commit at this point.在这一点上进行提交。
Then, however you run your application migrations in a deployed environment, run django_rename_app before you run your migrations in that process.然后,无论您在已部署的环境中运行应用程序迁移,请在该过程中运行迁移之前运行django_rename_app 。
ie Before "python manage.py migrate --noinput", as the example below shows.即在“python manage.py migrate --noinput”之前,如下例所示。
# Before
python manage.py collectstatic --noinput
python manage.py migrate --noinput
gunicorn my_project.wsgi:application
# After
python manage.py collectstatic --noinput
python manage.py rename_app old_app new_app
python manage.py migrate --noinput
gunicorn my_project.wsgi:application
This will update the app name in the following internal Django database tables:这将更新以下内部 Django 数据库表中的应用程序名称:
And rename the prefix of all of your tables to start with your new app name, rather than the old one.并重命名所有表的前缀,以您的新应用程序名称开头,而不是旧名称。
That's it.就是这样。
Note : Its better to use your IDE's/text editor's find & replace function for making changes in the various files.注意:最好使用 IDE/文本编辑器的查找和替换功能对各种文件进行更改。
My simple alternative that avoids manual database manipulation (similar to https://stackoverflow.com/a/64133141/1608851 ), works well in a CI/CD, and is reversible.我的简单替代方案避免了手动数据库操作(类似于https://stackoverflow.com/a/64133141/1608851 ),在 CI/CD 中运行良好,并且是可逆的。
from django.db import migrations
sql = """
ALTER TABLE oldapp_examplemodel RENAME TO newapp_examplemodel;
UPDATE django_migrations SET app ='newapp' WHERE app ='oldapp';
UPDATE django_content_type SET app_label ='newapp' WHERE app_label ='oldapp';
"""
reverse_sql = """
ALTER TABLE newapp_examplemodel RENAME TO oldapp_examplemodel;
UPDATE django_migrations SET app ='oldapp' WHERE app ='newapp';
UPDATE django_content_type SET app_label ='oldapp' WHERE app_label ='newapp';
"""
class Migration(migrations.Migration):
dependencies = [
('oldapp', '0001_initial'),
]
operations = [
migrations.RunSQL(sql, reverse_sql)
]
class ExampleModel(models.Model):
# normal column definitions...
class Meta:
db_table = "newapp_examplemodel" # add this line to the meta class
db_table
overrides from the model meta classes.从 model 元类中删除db_table
覆盖。Notes:笔记:
django_migrations
table will retain a row with the old app, because that row is added after our new migration was run, but before it was registered under the new app name. django_migrations
表将保留旧应用程序的一行,因为该行是在我们的新迁移运行之后添加的,但在它以新应用程序名称注册之前添加。 It should be okay to leave that as is.保持原样应该没问题。Why not just use the option Find and Replace.为什么不直接使用“查找和替换”选项。 (every code editor has it)? (每个代码编辑器都有)?
For example Visual Studio Code (under Edit option):例如 Visual Studio Code(在编辑选项下):
You just type in old name and new name and replace everyhting in the project with one click.您只需输入旧名称和新名称,然后一键替换项目中的所有内容。
NOTE : This renames only file content, NOT file and folder names.注意:这只会重命名文件内容,而不是文件和文件夹名称。 Do not forget renaming folders, eg.不要忘记重命名文件夹,例如。 templates/my_app_name/
rename it to templates/my_app_new_name/
templates/my_app_name/
将其重命名为templates/my_app_new_name/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.