Django - проблема импорта типовых моделей

Я действительно этого не понимаю, поэтому, если кто-то может объяснить, как это работает, я бы очень это оценил. У меня два приложения: учетные записи и тема... вот список моих настроек:

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

Это какая-то проблема с циклическим импортом? Я пробовал использовать ленивую ссылку, но это тоже не работает!

Ответ 1

Удалите импорт Theme и вместо этого используйте имя модели в качестве строки.

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

Ответ 2

Что-то, о чем я не упоминал, где-либо достаточно подробно описано, как правильно сформулировать строку внутри ForeignKey при ссылке на модель в другом приложении. Эта строка должна быть app_label.model_name. И, что очень важно, app_label - это не вся строка в INSTALLED_APPS, а только последний ее компонент. Поэтому, если ваш INSTALLED_APPS выглядит так:

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

чтобы включить ForeignKey в модель в app2 в модели app1, вы должны сделать:

app2_themodel = ForeignKey('app2.TheModel')

Я потратил довольно много времени на решение проблемы циклического импорта (так что я не мог просто from another.path.to.app2.models import TheModel), прежде чем наткнулся на это, google/SO не помогло (все примеры имели однокомпонентные пути к приложениям) так что, надеюсь, это поможет другим новичкам django.

Ответ 3

Используйте get_model функцию из django.db.models, которая предназначена для ленивых импортных моделей.

MyModel = get_model('app_name', 'ModelName')

В вашем случае:

Theme = get_model('themes', 'Theme')

Теперь вы можете использовать Theme