Django - 圆形模型导入问题

Posted

技术标签:

【中文标题】Django - 圆形模型导入问题【英文标题】:Django - Circular model import issue 【发布时间】:2011-05-21 17:05:22 【问题描述】:

我真的不明白这个,所以如果有人能解释它是如何工作的,我将非常感激。我有两个应用程序,帐户和主题...这是我的设置列表:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'accounts',
    'themes',
)

在帐户中,我正在尝试这样做:

from themes.models import Theme

class Account(models.Model):
    ACTIVE_STATUS = 1
    DEACTIVE_STATUS = 2
    ARCHIVE_STATUS = 3
    STATUS_CHOICES = (
        (ACTIVE_STATUS, ('Active')),
        (DEACTIVE_STATUS, ('Deactive')),
        (ARCHIVE_STATUS, ('Archived')),
    )

    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=250)
    slug = models.SlugField(unique=True, verbose_name='URL Slug')
    status = models.IntegerField(choices=STATUS_CHOICES, default=ACTIVE_STATUS, max_length=1)
    owner = models.ForeignKey(User)
    enable_comments = models.BooleanField(default=True)
    theme = models.ForeignKey(Theme)
    date_created = models.DateTimeField(default=datetime.now)

在我的主题模型中:

class Theme(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=250)
    slug = models.SlugField(unique=True, verbose_name='URL Slug')
    date_created = models.DateTimeField(default=datetime.now)

class Stylesheet(models.Model):
    id = models.AutoField(primary_key=True)
    account = models.ForeignKey(Account)
    date_created = models.DateTimeField(default=datetime.now)
    content = models.TextField()

Django 正在踢出以下错误:

from themes.models import Theme
ImportError: cannot import name Theme

这是某种循环导入问题吗?我尝试过使用惰性引用,但这似乎也不起作用!

【问题讨论】:

看起来确实是循环导入的问题。为什么需要从定义Theme的模块中导入Account 对不起,我没有正确粘贴我的主题模型,我已经更新了我的帖子。我在 Stylesheet 类中使用它。 【参考方案1】:

删除Theme的导入,改为使用模型名称作为字符串。

theme = models.ForeignKey('themes.Theme')

【讨论】:

实际上需要'themes.Theme',因为它在不同的应用程序中。 啊,那行得通,我之前只尝试过“主题”,但没有用。谢谢。这样做对性能有什么影响吗?如果可能的话,我想保持我的查找不懒惰:) @Daniel:已更新。 @Hanpan:一个小的,是的。但只有一次。【参考方案2】:

在其他应用程序中引用模型时,如何在 ForeignKey 中正确地制定字符串是我在任何地方都没有看到的详细信息。此字符串需要为app_label.model_name。而且,非常重要的是,app_label 不是 INSTALLED_APPS 中的整行,而只是它的最后一个组件。所以如果你的 INSTALLED_APPS 看起来像这样:

INSTALLED_APPS = (
...
    'path.to.app1',
    'another.path.to.app2'
)

然后要将 ForeignKey 包含到 app1 模型中的 app2 中的模型,您必须这样做:

app2_themodel = ForeignKey('app2.TheModel')

我花了很长时间试图解决循环导入问题(所以我不能只是 from another.path.to.app2.models import TheModel),然后我偶然发现了这个问题,google/SO 没有帮助(所有示例都有单组件应用程序路径),所以希望这将有助于其他 django 新手。

【讨论】:

【参考方案3】:

到 Django 1.7:

使用 django.db.models 中的 get_model 函数,该函数专为惰性模型导入而设计。:

from django.db.models import get_model
MyModel = get_model('app_name', 'ModelName')

在你的情况下:

from django.db.models import get_model
Theme = get_model('themes', 'Theme')

现在你可以使用Theme

对于 Django 1.7+:

from django.apps import apps
apps.get_model('app_label.model_name')

【讨论】:

使用apps.get_model(app_label, model_name)apps.get_model('app_label.model_name') in Django 1.7+【参考方案4】:

既然 Django 1.7 正确的方法是这样走:

from django.apps import apps

YourModel = apps.get_model('your_app_name', 'YourModel')

见:https://docs.djangoproject.com/ja/1.9/ref/applications/#django.apps.apps.get_model

【讨论】:

还有一个单参数快捷语法:apps.get_model('your_app_name.YourModel') 方便在map 等中使用。【参考方案5】:

我遇到了同样的问题,但是在使用MyModel = get_model('app_name', 'ModelName') 时出现了一个新错误'raise AppRegistryNotReady("Models aren't loaded yet.")'

我尝试了此页面上的所有其他方法,但没有一个对我有用。 我修复它的方法是使用: MyModel = get_model('app_name', 'ModelName') 但实际上是在课堂上而不是在课堂外。

【讨论】:

以上是关于Django - 圆形模型导入问题的主要内容,如果未能解决你的问题,请参考以下文章

Django +2 ImportError:无法导入模型

在 Python 中动态生成导入,专门针对 Django 模型

django抽象模型继承导入

将数据从 excel 电子表格导入 django 模型

将旧 (Django 0.97) 模型数据导入/迁移到 Django 1.8 或更高版本

Django,将模型类导入新文件。导入错误尝试在没有已知父项的情况下进行相对导入