我在Django中修改了一个应用的名字,重命名了它的文件夹、导入和所有引用(模板/索引)。但是现在,当我试图运行python manage.py runserver时,我得到了这个错误

Error: Could not import settings 'nameofmynewapp.settings' (Is it on sys.path?): No module named settings

如何调试和解决此错误?有线索吗?


当前回答

有趣的问题!我很快就要给很多应用重命名了,所以我先做了个预演。

这种方法允许在原子步骤中取得进展,以最大限度地减少对正在重命名应用程序的其他开发人员的干扰。

请参阅答案底部的链接,以获得工作示例代码。

Prepare existing code for the move: Create an app config (set name and label to defaults). Add the app config to INSTALLED_APPS. On all models, explicitly set db_table to the current value. Doctor migrations so that db_table was "always" explicitly defined. Ensure no migrations are required (checks previous step). Change the app label: Set label in app config to new app name. Update migrations and foreign keys to reference new app label. Update templates for generic class-based views (the default path is <app_label>/<model_name>_<suffix>.html) Run raw SQL to fix migrations and content_types app (unfortunately, some raw SQL is unavoidable). 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). Rename the tables: Remove "custom" db_table. Run makemigrations so django can rename the table "to the default". Move the files: Rename module directory. Fix imports. Update app config's name. Update where INSTALLED_APPS references the app config. Tidy up: Remove custom app config if it's no longer required. If app config gone, don't forget to also remove it from INSTALLED_APPS.


示例解决方案:我已经创建了app-rename- Example,一个示例项目,在这里你可以看到我如何重命名一个应用程序,一次提交一次。

这个例子使用的是Python 2.7和Django 1.8,但我相信同样的过程至少可以在Python 3.6和Django 2.1上工作。

其他回答

按照以下步骤在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)来自动化上述步骤(未经测试的代码。我已经警告过你了!)

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/

简单的4步重命名Django项目中现有的应用程序,没有任何痛苦或数据丢失。

步骤1

重命名app文件夹。在本例中,“old_app”是我们的旧名称,“new_app”是我们的新名称。

Mv ./old_app ./new_app . Mv ./old_app . Mv

步骤2

更新所有引用旧文件夹的导入以引用新文件夹。

例如:

# Before 
from myproject.old_app import models

# After
from myproject.new_app import models

步骤3

更新Django迁移中旧的应用程序名称引用。

你可能需要做的一些改变:

# 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'
)

步骤4

在这一点上做出承诺。

然后,无论您在已部署的环境中运行应用程序迁移,都要在该进程中运行迁移之前运行django_rename_app。

即在"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

这将更新Django内部数据库表中的应用程序名称:

django_content_type django_migrations

并重命名所有表的前缀,以新的应用程序名称开始,而不是旧的。

就是这样。

注意:最好使用IDE /文本编辑器的查找和替换功能来更改各种文件。

如果你使用Pycharm,重命名应用程序是非常容易的重构(Shift+F6默认)的所有项目文件。 但是要确保你删除了项目目录及其子目录中的__pycache__文件夹。也要小心,因为它也重命名注释,你可以排除在重构预览窗口,它会显示给你。 此外,你还必须在重命名应用的apps.py中重命名OldNameConfig(AppConfig):。

如果你不想丢失数据库中的数据,你必须手动在数据库中查询,就像前面提到的答案。

如果你正在使用PyCharm并且项目在重命名后停止工作:

编辑运行/调试配置并更改环境变量DJANGO_SETTINGS_MODULE,因为它包含了您的项目名称。 进入Settings / Languages & Frameworks / Django,更新Settings文件的位置。