我在Django中修改了一个应用的名字,重命名了它的文件夹、导入和所有引用(模板/索引)。但是现在,当我试图运行python manage.py runserver时,我得到了这个错误
Error: Could not import settings 'nameofmynewapp.settings' (Is it on sys.path?): No module named settings
如何调试和解决此错误?有线索吗?
我在Django中修改了一个应用的名字,重命名了它的文件夹、导入和所有引用(模板/索引)。但是现在,当我试图运行python manage.py runserver时,我得到了这个错误
Error: Could not import settings 'nameofmynewapp.settings' (Is it on sys.path?): No module named settings
如何调试和解决此错误?有线索吗?
当前回答
在很多情况下,我认为@allcaps的答案效果很好。
然而,有时确实需要重命名应用程序,例如提高代码可读性或防止混淆。
大多数其他答案都涉及手工数据库操作或对现有迁移进行修补,我不太喜欢这种方法。
作为一种替代方法,我喜欢用想要的名称创建一个新的应用程序,复制所有内容,确保它可以工作,然后删除原来的应用程序:
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. 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. Create a data migration that copies the relevant data from the original app's tables into the new app's tables, and migrate again.
此时,一切仍然正常,因为原始应用程序及其数据仍然在原地。
现在你可以重构所有的依赖代码,所以它只使用新的应用程序。有关需要注意的例子,请参阅其他答案。 一旦你确定一切正常,你可以删除原来的应用程序。这涉及到另一种(模式)迁移。
这样做的好处是,每一步都使用正常的Django迁移机制,不需要手动操作数据库,我们可以跟踪源代码控制中的所有内容。此外,我们将保留原始应用程序及其数据,直到我们确定一切正常为止。
其他回答
Django 1.7新增了一个应用注册表,用于存储配置并提供自省功能。这个机制让你改变几个应用程序的属性。
我想说的主要观点是,重命名应用并不总是必要的:通过应用配置,可以解决冲突的应用。但如果你的应用需要友好的命名,这也是一种方法。
例如,我想把我的民意调查应用程序命名为“用户反馈”。它是这样的:
在polls目录下创建一个apps.py文件:
from django.apps import AppConfig
class PollsConfig(AppConfig):
name = 'polls'
verbose_name = "Feedback from users"
在polls/__init__.py中添加默认应用配置:
default_app_config = 'polls.apps.PollsConfig'
更多应用配置请访问:https://docs.djangoproject.com/en/1.7/ref/applications/
如果你使用Pycharm,重命名应用程序是非常容易的重构(Shift+F6默认)的所有项目文件。 但是要确保你删除了项目目录及其子目录中的__pycache__文件夹。也要小心,因为它也重命名注释,你可以排除在重构预览窗口,它会显示给你。 此外,你还必须在重命名应用的apps.py中重命名OldNameConfig(AppConfig):。
如果你不想丢失数据库中的数据,你必须手动在数据库中查询,就像前面提到的答案。
按照以下步骤在Django中更改应用程序的名称:
Rename the folder which is in your project root Change any references to your app in their dependencies, i.e. the app's views.py, urls.py , manage.py , and settings.py files. Edit the database table django_content_type with the following command: UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>' Also, if you have models, you will have to rename the model tables. For postgres, use ALTER TABLE <oldAppName>_modelName RENAME TO <newAppName>_modelName. For mysql too, I think it is the same (as mentioned by @null_radix). (For Django >= 1.7) Update the django_migrations table to avoid having your previous migrations re-run: 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+; If someone knows for sure please update here. If your models.py 's Meta Class has app_name listed, make sure to rename that too (mentioned by @will). If you've namespaced your static or templates folders inside your app, you'll also need to rename those. For example, rename old_app/static/old_app to new_app/static/new_app. For renaming django models, you'll need to change django_content_type.name entry in DB. For postgreSQL, use UPDATE django_content_type SET name='<newModelName>' where name='<oldModelName>' AND app_label='<OldAppName>' Update 16Jul2021: Also, the __pycache__/ folder inside the app must be removed, otherwise you get EOFError: marshal data too short when trying to run the server. Mentioned by @Serhii Kushchenko
元点(如果使用virtualenv):值得注意的是,如果您重命名包含virtualenv的目录,那么env中可能会有几个包含绝对路径的文件,也需要更新。如果你得到类似ImportError: No module named…这可能就是罪魁祸首。(感谢@danyamachine提供这篇文章)。
其他参考资料:你可能也想参考下面的链接,以获得更完整的图片:
用Django和South重命名应用 我如何将一个模型从一个django应用程序迁移到一个新的? 如何更改Django应用程序的名称? 使用Django South进行向后迁移 使用Django/South重命名模型的最简单方法? Python代码(感谢A.Raouf)来自动化上述步骤(未经测试的代码。我已经警告过你了!) Python代码(感谢rafaponieman)来自动化上述步骤(未经测试的代码。我已经警告过你了!)
重新迁移,寻找更干净的板块。
这可以毫不痛苦地做,如果其他应用程序没有外键模型从应用程序被重命名。检查并确保他们的迁移文件没有列出任何来自此迁移的迁移。
Backup your database. Dump all tables with a) data + schema for possible circular dependencies, and b) just data for reloading. Run your tests. Check all code into VCS. Delete the database tables of the app to be renamed. Delete the permissions: delete from auth_permission where content_type_id in (select id from django_content_type where app_label = '<OldAppName>') Delete content types: delete from django_content_type where app_label = '<OldAppName>' Rename the folder of the app. Change any references to your app in their dependencies, i.e. the app's views.py, urls.py , 'manage.py' , and settings.py files. Delete migrations: delete from django_migrations where app = '<OldAppName>' If your models.py 's Meta Class has app_name listed, make sure to rename that too (mentioned by @will). If you've namespaced your static or templates folders inside your app, you'll also need to rename those. For example, rename old_app/static/old_app to new_app/static/new_app. If you defined app config in apps.py; rename those, and rename their references in settings.INSTALLED_APPS Delete migration files. Re-make migrations, and migrate. Load your table data from backups.
在很多情况下,我认为@allcaps的答案效果很好。
然而,有时确实需要重命名应用程序,例如提高代码可读性或防止混淆。
大多数其他答案都涉及手工数据库操作或对现有迁移进行修补,我不太喜欢这种方法。
作为一种替代方法,我喜欢用想要的名称创建一个新的应用程序,复制所有内容,确保它可以工作,然后删除原来的应用程序:
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. 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. Create a data migration that copies the relevant data from the original app's tables into the new app's tables, and migrate again.
此时,一切仍然正常,因为原始应用程序及其数据仍然在原地。
现在你可以重构所有的依赖代码,所以它只使用新的应用程序。有关需要注意的例子,请参阅其他答案。 一旦你确定一切正常,你可以删除原来的应用程序。这涉及到另一种(模式)迁移。
这样做的好处是,每一步都使用正常的Django迁移机制,不需要手动操作数据库,我们可以跟踪源代码控制中的所有内容。此外,我们将保留原始应用程序及其数据,直到我们确定一切正常为止。