Django - 循环模型导入问题

Han*_*pan 102 django django-models

我真的没有得到这个,所以如果有人能解释这是如何工作的,我会非常感激.我有两个应用程序,帐户和主题......这是我的设置列表:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'accounts',
    'themes',
)
Run Code Online (Sandbox Code Playgroud)

在帐户中,我试图这样做:

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)
Run Code Online (Sandbox Code Playgroud)

在我的主题模型中:

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()
Run Code Online (Sandbox Code Playgroud)

Django正在推出以下错误:

from themes.models import Theme
ImportError: cannot import name Theme
Run Code Online (Sandbox Code Playgroud)

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

Ign*_*ams 184

删除导入Theme并将模型名称用作字符串.

theme = models.ForeignKey('themes.Theme')
Run Code Online (Sandbox Code Playgroud)

  • 实际上,它需要是''themes.Theme'',因为它在不同的应用程序中. (4认同)

Bog*_*tyr 49

我在任何地方都没有提到的足够详细的内容是在引用不同应用程序中的模型时如何正确地在ForeignKey中制定字符串.这个字符串需要app_label.model_name.而且,非常重要的app_label是,它不是INSTALLED_APPS中的整行,而只是它的最后一个组成部分.因此,如果您的INSTALLED_APPS如下所示:

INSTALLED_APPS = (
...
    'path.to.app1',
    'another.path.to.app2'
)
Run Code Online (Sandbox Code Playgroud)

然后在app1模型的app2中包含一个ForeignKey模型,你必须这样做:

app2_themodel = ForeignKey('app2.TheModel')
Run Code Online (Sandbox Code Playgroud)

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

  • 我总是加上'模特'!谢谢你的好消息! (2认同)
  • 哇,我不敢相信我浪费了2个小时的时间,直到找到这个答案!谢谢!对我来说仍然没有意义,为什么我不添加模型,但只要它有效. (2认同)

Ran*_*u R 48

Upto Django 1.7:

使用get_model从中django.db.models为懒惰模型导入设计的函数:

from django.db.models import get_model
MyModel = get_model('app_name', 'ModelName')
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

from django.db.models import get_model
Theme = get_model('themes', 'Theme')
Run Code Online (Sandbox Code Playgroud)

现在你可以使用了 Theme

对于Django 1.7+:

from django.apps import apps
apps.get_model('app_label.model_name')
Run Code Online (Sandbox Code Playgroud)

  • 使用`apps.get_model(app_label,model_name)`或`apps.get_model('app_label.model_name')`[在Django 1.7+中](https://docs.djangoproject.com/en/1.7/ref/applications/# django.apps.apps.get_model) (10认同)

and*_*abs 35

由于Django 1.7正确的方法是这样的:

from django.apps import apps

YourModel = apps.get_model('your_app_name', 'YourModel')
Run Code Online (Sandbox Code Playgroud)

请参阅:https://docs.djangoproject.com/ja/1.9/ref/applications/#django.apps.apps.get_model

  • 还有一个单arg快捷语法:`apps.get_model('your_app_name.YourModel')`便于在`map`等中使用. (4认同)