Django-循環モデルのインポートの問題


116

私は本当にこれを取得していないので、誰かがこれがどのように機能するかを説明できれば、私はそれを非常に感謝します。私は2つのアプリケーション、アカウントとテーマを持っています...これは私の設定リストです:

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
循環インポートの問題のように見えます。が定義さAccountれているモジュールからインポートする必要があるのはなぜThemeですか?
Dominic Rodger、

申し訳ありませんが、テーマモデルを正しく貼り付けていません。投稿を更新しました。Stylesheetクラスで使用しています。
Hanpan

回答:


213

のインポートを削除し、Theme代わりにモデル名を文字列として使用してください。

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

5
実際'themes.Theme'には別のアプリにあるので、それはである必要があります。
Daniel Roseman、

ああ、それはうまくいきました、私は以前に「テーマ」だけを試していましたが、うまくいきませんでした。ありがとう。この方法でパフォーマンスに影響を与えることはありますか?可能であれば、ルックアップを遅延させないようにしたいと思います:)
Hanpan

@ダニエル:更新されました。@はんぱん:小さなもの、はい。しかし、一度だけ。
Ignacio Vazquez-Abrams

56

Django 1.7まで:

遅延モデルのインポート用に設計されたget_model関数を使用しますdjango.db.models

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')

10
Django 1.7apps.get_model(app_label, model_name)以降apps.get_model('app_label.model_name')
phoibos

51

他のアプリでモデルを参照する際に、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は助けになりませんでした(すべての例に単一のコンポーネントアプリパスがありました)。ジャンゴ初心者。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.