2010-12-07 11 views
77

Realmente no entiendo esto, así que si alguien pudiera explicar cómo funciona esto, lo agradecería muchísimo. Tengo dos aplicaciones, cuentas y Productor ... aquí está mi lista de ajustes:Django - Número de importación de modelo circular

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

En cuentas, yo estoy tratando de hacer esto:

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) 

Y en mi modelo tema:

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 está lanzando el siguiente error:

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

¿Es esto algún tipo de problema circular de importación? Intenté usar una referencia perezosa, ¡pero eso tampoco parece funcionar!

+1

Parece un problema con las importaciones circulares. ¿Por qué necesita importar 'Cuenta' del módulo donde' Tema' está definido? –

+0

Lo siento, no pegué mi modelo de temas correctamente, he actualizado mi publicación. Lo estoy usando en la clase de hoja de estilo. – Hanpan

Respuesta

137

Elimine la importación de Theme y en su lugar use el nombre del modelo como una cadena.

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

En realidad eso tiene que ser '' themes.Theme'', ya que está en una aplicación diferente. –

+0

Ahh, eso funcionó, solo estaba intentando 'Theme' antes y no funcionó. Gracias. ¿Hay algún tipo de golpe de rendimiento por hacerlo de esta manera? Me gustaría mantener mis búsquedas no vagas si es posible :) – Hanpan

+0

@Daniel: Actualizado. @Hanpan: uno pequeño, sí. Pero solo una vez –

44

algo que no he visto mencionado en cualquier lugar con suficiente detalle es cómo formular correctamente la cadena dentro de ForeignKey al hacer referencia a un modelo en una aplicación diferente. Esta cadena debe ser app_label.model_name. Y, muy importante, el app_label no es toda la línea en INSTALLED_APPS, sino solo el último componente de él. Por lo tanto si su INSTALLED_APPS se ve así:

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

entonces para incluir un ForeignKey a un modelo en el app2 en un modelo app1, debe hacer:

app2_themodel = ForeignKey('app2.TheModel') 

Pasé mucho tiempo tratando de resolver un problema de importación circular (así que no pude simplemente from another.path.to.app2.models import TheModel) antes de tropezar con esto, google/SO no fue de ayuda (todos los ejemplos tenían rutas de aplicación de componente único), así que con suerte esto ayudará a otros novatos de django.

+1

Ambas respuestas arriba ayudaron, pero esto es lo que hice mal. ¡Muchas gracias! – Guerry

+2

¡siempre agregué 'modelos'! ¡Gracias por el gran consejo! – Ron

+2

¡Guau, no puedo creer que haya desperdiciado 2 horas de tiempo hasta que encontré esta respuesta! ¡Gracias! Aún no tiene sentido para mí por qué no agrego modelos, pero siempre y cuando funcione. –

34

Uso get_model función de django.db.models que está diseñado para la importación modelo perezosos .:

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

En su caso:

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

Ahora puede utilizar Theme

+8

Use 'apps.get_model (app_label, model_name)' o 'apps.get_model ('app_label.model_name')' [en Django 1.7+] (https://docs.djangoproject.com/en/1.7/ref/applications/ # django.apps.apps.get_model) – phoibos

Cuestiones relacionadas