156 Stimmen

Django - Problem mit zirkulärem Model-Import

Das verstehe ich wirklich nicht, also wenn jemand erklären könnte, wie das funktioniert, würde ich das sehr schätzen. Ich habe zwei Anwendungen, Accounts und Theme... hier ist meine Einstellungsliste:

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

In Accounts versuche ich dies zu machen:

from themes.models import Theme

class Account(models.Model):
    ACTIVE_STATUS = 1
    DEACTIVE_STATUS = 2
    ARCHIVE_STATUS = 3
    STATUS_CHOICES = (
        (ACTIVE_STATUS, ('Aktiv')),
        (DEACTIVE_STATUS, ('Deaktiviert')),
        (ARCHIVE_STATUS, ('Archiviert')),
    )

    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)

Und in meinem Theme-Modell:

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 gibt den folgenden Fehler aus:

from themes.models import Theme
ImportError: kann Namen Theme nicht importieren

Ist das eine Art von zirkulärem Importproblem? Ich habe versucht, eine verzögerte Referenz zu verwenden, aber das scheint auch nicht zu funktionieren!

284voto

Ignacio Vazquez-Abrams Punkte 735200

Entfernen Sie den Import von Theme und verwenden Sie stattdessen den Modellnamen als Zeichenkette.

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

72voto

Ranju R Punkte 2117

Bis Django 1.7:

Verwenden Sie die get_model-Funktion aus django.db.models, die für verzögerte Model-Imports konzipiert ist:

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

In Ihrem Fall:

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

Jetzt können Sie Theme verwenden

Für Django 1.7+:

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

54voto

Bogatyr Punkte 18985

Etwas, das ich nirgendwo ausreichend erwähnt gesehen habe, ist, wie man den String innerhalb von ForeignKey richtig formuliert, wenn man auf ein Modell in einer anderen App verweist. Dieser String muss app_label.model_name sein. Und ganz wichtig, das app_label ist nicht die gesamte Zeile in INSTALLED_APPS, sondern nur die letzte Komponente davon. Also, wenn Ihre INSTALLED_APPS so aussieht:

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

dann müssen Sie, um ein ForeignKey zu einem Modell in app2 in einem app1-Modell einzuschließen, Folgendes tun:

app2_themodel = ForeignKey('app2.TheModel')

Ich habe eine ziemlich lange Zeit damit verbracht, einen Fehler beim zirkulären Import zu lösen (also konnte ich nicht einfach from another.path.to.app2.models import TheModel benutzen), bevor ich darauf gestoßen bin. Google/SO konnte mir nicht helfen (alle Beispiele hatten App-Pfade mit nur einer Komponente), also hoffentlich hilft dies anderen Django-Neulingen.

46voto

andilabs Punkte 20478

Seit Django 1.7 sollte man wie folgt vorgehen:

from django.apps import apps

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

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

0voto

ryansl39 Punkte 1

Ich hatte das gleiche Problem, aber als ich MyModel = get_model('app_name', 'ModelName') benutzt habe, bekam ich einen neuen Fehler 'raise AppRegistryNotReady("Models aren't loaded yet.")'

Ich habe alle anderen Methoden auf dieser Seite ausprobiert, aber keine hat für mich funktioniert. Der Weg, wie ich es behoben habe, war folgender: MyModel = get_model('app_name', 'ModelName') aber tatsächlich innerhalb der Klasse anstatt außerhalb davon.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X