Instance in Django model with problem

4

I'm working on a project with multiple apps. The department app model is as follows:

from emails.models import GerenciarEmails

class Departamento(models.Model):
#modelo de grupos de disciplinas
class Meta:
    verbose_name = 'Departamento'
    verbose_name_plural = 'Departamentos'
titulo = models.CharField(max_length=255, verbose_name='Nome do Grupo')
watermark = models.FileField(upload_to = settings.MEDIA_ROOT+"/watermarks/", default=settings.MEDIA_ROOT+'/img/generico.gif')
cor = ColorField(blank=True)
gerencia = models.ForeignKey(GerenciarEmails)
docentes_responsaveis = models.ManyToManyField(settings.AUTH_USER_MODEL, null=True, blank=True,related_name="docentes_responsaveis_pelo_grupo", limit_choices_to={'docente':True})
def __unicode__(self):
    #Modo como o Modelo e Exibido na Lista na Adminstracao
    return unicode(self.titulo)

I've added the following instance to it:

gerencia = models.ForeignKey(GerenciarEmails)

ManageEmails is an email app modeling method. The import that is of interest is used, the others refer to other things.

With the insertion of this instance, Django gives the following error: ImportError: can not import name Department

Apparently it is not letting you enter this instance. Could someone help me on the reason for the error?

This is the ManageEmails method:

class GerenciarEmails(models.Model):
    class Meta:
        verbose_name = 'Gerenciar E-mails'
        verbose_name_plural = 'Gerenciar E-mails'
    departamento = models.ForeignKey(Departamento)
    def __unicode__(self):
        return self.departamento.titulo

As you can see, I use the Department method of models.py from the Departments app. If I put the import after this method, as is the suggestion of mgibsonbr , python gives another error:

ImportError: cannot import name Disciplina

It even makes sense, as ManageEmail needs the Department import.

    
asked by anonymous 12.11.2015 / 19:42

2 answers

3

First thing is to check the folder structure of your project, you may have to put

from seuprojeto.emails.models import GerenciarEmails

If it is not this, it is probably the problem that mgibsonbr said in the comments: "If your app A depends (imports) of B, and B in turn depends on A". Use the ForeignKey in this way to kill the problem:

gerencia = models.ForeignKey('emails.GerenciarEmails')
    
13.11.2015 / 03:44
2

Your error message is a hint of circular dependency . Did you happen to have a line in% w_ of%:

from departamentos.models import Departamento

? This code worked before because the app emails/models.py depended on emails , so when departamentos was loaded, it did import , it loaded the app emails/models.py integer , and then proceeded to read the contents of the departamentos app.

When you have emails passed also to depend on departamentos (by the way, what is causing the error is emails , not the creation of the field), then we have a problem:

  • Python starts reading import ; create the module, empty;
  • It reads the line that asks to import departamentos/models.py ; the module has not yet been read;
  • It starts reading emails.models ; create the module, empty;
  • It reads the line that asks to import emails/models.py ; the module exists but is empty;
  • It tries to read departamentos.models in the imported module; this name does not exist because the module is empty;
  • Departamento

Fixing this is not easy, and may involve refactoring your code (changing app templates). If you were sure that the ImportError: cannot import name Departamento app would be loaded before the emails app, you could put departamentos not at the beginning of the file, but after the import :

emails / models.py

... # Nada que faça uso de Departamento

class GerenciarEmails(models.Model):
    ...

from departamentos.models import Departamento

... # Coisas que dependem de Departamento

So the app GerenciarEmails would be read to the point where it sets emails , with the import the GerenciarEmails app would be read integer (and it would have access to departamentos , since it has already been included in the module) and then the GerenciarEmails would continue reading normally. It works, the hard thing is to guarantee this reading order (if emails/models.py was read first, finished, there is no way to "fix" the order).

In the Puam Dias response he suggests specifying the foreign key using a string instead of a direct reference for a model:

gerencia = models.ForeignKey('emails.GerenciarEmails')

If you do this, regardless of the departamentos app, it can work (I can not say I've never used this build). If nothing works out, then you just have to move your models from one app to another until there are no more circular dependencies between apps.

    
13.11.2015 / 20:09