【问题标题】:Connecting Models from different Apps - Django连接来自不同应用程序的模型 - Django
【发布时间】:2016-10-13 09:51:57
【问题描述】:

鉴于我有 4 个模型:

  • Project
  • User(来自 django.contrib.auth.models)
  • Sentence
  • Translation

我的 django 项目目录的结构如下:

 \myprojname
     \project
         models.py
     \data
         models.py

User 模型独立于 Projects 和 Sentences 模型,但它通过 ForeignKey 链接到 Projects 模型:

myprojname/projects/models.py 看起来像这样:

from django.db import models
from django.contrib.auth.models import User

class Project(models.Model):
    project_id = models.AutoField(primary_key=True)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)

    name = models.CharField(max_length=140)
    # Admin user for the particular *Project* object.
    # Have the rights to write to the *Sentence* model.
    owner = models.ForeignKey(User)
    # Worker users that only have write access to the *Translation model.
    workers = models.ForeignKey(User, blank=True)

myprojname/data/models.py 看起来像这样:

from django.db import models
from django.contrib.auth.models import User

class Sentence(models.Model):
    text = models.TextField()
    translations = models.ManyToManyField('Translation', blank=True)

class Translation(models.Model):
    text = models.TextField()
    translator = models.ForeignKey(User)

现在Project 模型未连接到Sentence 模型。

我尝试将它与相对导入连接,即在myprojname/projects/models.py 中,我做到了:

from django.db import models
from django.contrib.auth.models import User
from ..data import Sentence

class Project(models.Model):
    # ...
    sentences = models.ForeignKey(Sentence)

但它在Python2.7 中返回了ValueError:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/runserver.py", line 109, in inner_run
    autoreload.raise_last_exception()
  File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line 249, in raise_last_exception
    six.reraise(*_exception)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/autoreload.py", line 226, in wrapper

    fn(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/usr/local/lib/python2.7/dist-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/usr/local/lib/python2.7/dist-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/alvas/data-project/myprojname/project/models.py", line 5, in <module>
    from ..data import Sentence
ValueError: Attempted relative import beyond toplevel package

在Python3 中,同样的错误:

Traceback (most recent call last):
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 109, in inner_run
    autoreload.raise_last_exception()
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/utils/autoreload.py", line 249, in raise_last_exception
    six.reraise(*_exception)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise

    raise value.with_traceback(tb)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 662, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/home/alvas/data-project/myprojname/project/models.py", line 5, in <module>
    from ..data import Sentence
ValueError: attempted relative import beyond top-level package

当我尝试在Python3 中进行非相对导入时:

from django.db import models
from django.contrib.auth.models import User
from myprojname.data import Sentence

class Project(models.Model):
    # ...
    sentences = models.ForeignKey(Sentence)

我明白了:

Traceback (most recent call last):
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 109, in inner_run

    autoreload.raise_last_exception()
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/utils/autoreload.py", line 249, in raise_last_exception
    six.reraise(*_exception)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/home/alvas/.virtualenvs/payer/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 662, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/home/alvas/data-project/myprojname/project/models.py", line 5, in <module>
    from myprojname.data import Sentence
ImportError: No module named 'myprojname.data'

如何连接来自不同应用的模型?


已编辑

当我在myprojname.project.models.py 中使用from data import Sentence 时,它会抛出一个ImportError:

Traceback (most recent call last):
  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 109, in inner_run
    autoreload.raise_last_exception()
  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/site-packages/django/utils/autoreload.py", line 249, in raise_last_exception
    six.reraise(*_exception)
  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)

  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/home/alvas/.virtualenvs/statnlp/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 662, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/home/alvas/data-project/myprojname/project/models.py", line 5, in <module>
    from data import Sentence
ImportError: cannot import name 'Sentence'

【问题讨论】:

  • 一个问题,当你可以做 from data.models import Sentence 时,为什么要相对导入?
  • 非相对导入将是 from data.models import Sentence 而不是 from myprojname.data import Sentence
  • 对不起,你不得不从 data.models 导入句子,我的错。
  • 啊太棒了!现在可以from data.models import Sentence !!知道是什么让 Django 与普通 python 不同,因此它可以在不位于正确目录或相对导入中的情况下进行导入?
  • 什么都没有。 Django 与这里的“普通 Python”没有任何不同。

标签: python django web-applications django-models orm


【解决方案1】:

您的导入应该是from data.models import Sentence 而不是from myprojname.data import Sentence。

【讨论】:

  • 谢谢拉杰什!!!但是知道是什么让 Django 与普通 python 不同,这样它就可以在不位于正确目录或相对导入中的情况下进行导入?
  • 这方面我不太确定。
猜你喜欢
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
相关资源
最近更新 更多