【问题标题】:Import app in django project在 django 项目中导入应用程序
【发布时间】:2015-10-13 13:00:12
【问题描述】:

我在 django 项目的另一个应用程序中导入应用程序时遇到问题。 我知道有几个关于这个主题的问题/asnwsers,相信我我读过很多,甚至一些关于 python 导入的。

这是我的项目树(我会放真正的文件夹名称):

was/ # full path from my computer /home/user/project/was
....was/ #django project created by django-admin startproject 'was'
    ....manage.py
    ....artists/ #first app
        ....migrations/
        ....templates/
        ....__init__.py 
        ....other_python_files.py
    ....crew/ #second app    
        ....migrations/
        ....templates/
        ....__init__.py
        ....some_files.py
    ....was/ # folder containing settings.py, main urls.py
        ....__init__.py

我的第一个项目(/home/user/project/was)包含 virtualenv 生成的文件夹(python3.4)。

我检查了我的 python 路径 sys.path 和我在 Pycharm 中的项目结构,有 /home/user/project/was。

当我在 PyCharm 中执行此操作时,我的自动补全工作正常:

from ..crew.models import MyClass #here i'm in a artists app file

但我收到了ValueError :attempted relative import beyond top-level package when import app

现在,同样的场景,在艺术家应用程序中导入一个船员班,但是:

from was.crew.models import MyClass

自动补全在 pycharm 中运行良好,但这次我得到了经典的 ImportError :no name was.crew

我通过在我的 settings.py 中添加这一行来找到解决方案:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR)) # add this line

请注意,BASE_DIR 已存在于设置中。 现在我可以这样做了:

from crew.models import MyClass

在这里我没有出错(更改 Pycharm 中的一些设置以使自动完成工作)。

这行得通,但我真的很想知道为什么我必须添加这一行以及为什么我的两次第一次尝试都不起作用。

我对包、pythonpath 等有点迷茫(这就是我在架构中指定所有 __init__.py 文件的原因)。

不应该 from ..anotherapp.models import Class 在 settings.py 中不拉皮条就可以正常工作吗?

无论如何,我应该保留我的解决方案还是不是一件好事?

提前感谢您的任何回复。

PS:请注意,我已经尝试在我的第一个和第二个文件夹中有 __init__.py 文件,但没有成功。

【问题讨论】:

    标签: python django python-3.x python-import


    【解决方案1】:

    示例项目(有效)。

    项目结构

    test_project/
      test_project/
        settings.py
        urls.py
        wsgi.py 
      app1/
        models.py
      app2/
        models.py
    

    app1/models.py

    from django.db import models
    
    class Restaurant(models.Model):
        name = models.CharField(max_length=255)
    

    app2/models.py

    from django.db import models
    from app1.models import Restaurant
    
    class Waiter(models.Model):
        restaurant = models.ForeignKey(Restaurant)
        name = models.CharField(max_length=255)
    

    在您的情况下,from ..crew.models import MyClassfrom crew.models import MyClass 都应该可以工作。我的猜测是,当您(或 PyCharm)在 app 目录中时,您(或 PyCharm)会尝试运行某些文件或导入模块。当前目录(无论是什么意思)应该是was(由django-admin.exe 创建的目录。希望对您有所帮助。

    【讨论】:

    • 当我启动我的服务器并转到 localhost:8000 时实际触发的错误。是的,它应该可以工作(实际上可以在 pycharm 中工作,它会检索我的应用程序树)但是 django 会引发错误。会不会是 virtualenv python lib 在文件夹树中放置得太高的问题?
    • 我在我的问题中写的那些。无论我从 python 路径中删除条目并执行 app1.models 似乎都可以在没有我的设置的情况下工作。谢谢你的回答!
    【解决方案2】:

    在 django 项目中,您不需要提供从根目录到项目目录的路径。此外,BASE_DIR 是 django 项目的路径,当您在 django 中导入任何应用程序时,只需使用其名称导入即可。

    所以你的导入将是。

    from crew.models import MyClass
    

    【讨论】:

    • 是的,现在我删除了 python 路径中的条目(我强制的那个)并且它可以工作。不知道为什么,但写 from crew.models import MyClass 可以正常工作。感谢您的回答。
    • @Bestasttung 很高兴是我的。它工作正常,因为 BASE_DIR 在你的 django 项目的 settings.py 中映射了 django 应用程序的路径。查看这个 django 文档link
    【解决方案3】:

    我认为这对你有帮助!我为同样的问题苦苦挣扎了几天。我有所有 init.py 文件。我最终不得不将源根设置为 project_dir:

    右击project_dir,Mark Directory as > Sources Root

    它有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 2023-03-10
      • 2014-06-22
      • 2021-08-10
      相关资源
      最近更新 更多