Django - Masalah impor model melingkar


116

Saya benar-benar tidak mengerti ini, jadi jika seseorang dapat menjelaskan cara kerjanya, saya akan sangat menghargainya. Saya memiliki dua aplikasi, Akun dan Tema ... berikut adalah daftar pengaturan saya:

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

Di akun, saya mencoba melakukan ini:

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)

Dan dalam model tema saya:

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 menendang kesalahan berikut:

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

Apakah ini semacam masalah impor melingkar? Saya sudah mencoba menggunakan referensi malas, tetapi tampaknya itu juga tidak berhasil!


1
Sepertinya masalah dengan impor melingkar. Mengapa Anda perlu mengimpor Accountdari modul di mana Themeditentukan?
Dominic Rodger

Maaf, saya tidak menempelkan model Tema saya dengan benar, saya telah memperbarui posting saya. Saya menggunakannya di kelas Stylesheet.
Hanpan

Jawaban:


213

Hapus impor Themedan gunakan nama model sebagai string.

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

5
Sebenarnya itu perlu 'themes.Theme', karena ada di aplikasi yang berbeda.
Daniel Roseman

Ahh, itu berhasil, saya hanya mencoba 'Tema' sebelumnya dan tidak berhasil. Terima kasih. Apakah ada kinerja yang bagus untuk melakukannya dengan cara ini? Saya ingin agar pencarian saya tidak malas jika memungkinkan :)
Hanpan

@Daniel: Diperbarui. @Hanpan: Yang kecil, ya. Tapi hanya sekali.
Ignacio Vazquez-Abrams

56

Hingga Django 1.7:

Gunakan get_modelfungsi django.db.modelsyang dirancang untuk impor model malas .:

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

Dalam kasus Anda:

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

Sekarang Anda bisa menggunakan Theme

Untuk Django 1.7+:

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

10
Gunakan apps.get_model(app_label, model_name)atau apps.get_model('app_label.model_name') di Django 1.7+
phoibos

51

Sesuatu yang belum saya lihat disebutkan di mana pun dengan cukup detail adalah cara merumuskan string dengan benar di dalam ForeignKey saat mereferensikan model di aplikasi berbeda. String ini harus app_label.model_name. Dan, yang paling penting, app_labelbukan keseluruhan baris di INSTALLED_APPS, tetapi hanya komponen terakhirnya . Jadi jika INSTALLED_APPS Anda terlihat seperti ini:

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

lalu untuk menyertakan ForeignKey ke model di app2 dalam model app1, Anda harus melakukan:

app2_themodel = ForeignKey('app2.TheModel')

Saya menghabiskan waktu cukup lama untuk mencoba menyelesaikan masalah impor melingkar (jadi saya tidak bisa begitu saja from another.path.to.app2.models import TheModel) sebelum saya tersandung ke ini, google / SO tidak membantu (semua contoh memiliki jalur aplikasi komponen tunggal), jadi semoga ini akan membantu yang lain django pemula.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.