Instance in Django model with problem

Asked

Viewed 577 times

4

I’m working on a multi-app project. 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 added the following instance to it:

gerencia = models.ForeignKey(GerenciarEmails)

Mail management is a method of the email app model. The import what matters is this used, the others are related to other things.

With the insertion of this instance, Django gives the following error: Import: cannot import name Department

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

This is the method Managerial:

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, from models.py from the Departments app. If I put import after this method, as is the suggestion from mgibsonbr, python gives another error:

ImportError: cannot import name Disciplina

It kind of makes sense, because Managerial needs the import of Department.

  • Put the complete traceback error, it will help to solve your problem.

  • As in the question of another Stack user, http://stackoverflow.com/questions/17845366/importarror-cannot-import-name I believe it will help you.

  • If your app A depends on (imports) B, and B in turn depends on A, there is some problem in your modeling. Probably both models (Departamento and GerenciarEmails) should be part of the same app, and you should create the templates in the right order (dependent before dependent).

  • I think I’ve noticed your problem. Do you have the Department table with an FK for Managementmails, and Managementmails with an FK for Department?! This can’t happen, neither in Django nor in any relational database. Only one can have FK for the other. If the ratio is 1 to 1, choose one of the templates (I suggest Manage Mails) and put a Onetoonefield on it, and only. The other model will automatically have a field for the inverse ratio. But in the DB the foreign key must be in a single table.

2 answers

3

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

from seuprojeto.emails.models import GerenciarEmails

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

gerencia = models.ForeignKey('emails.GerenciarEmails')
  • Thanks for the suggestion, but they didn’t solve the problem. I am thinking that it should be more complicated, according to what the others said. I will make the mgibsonbr suggestion, and if necessary, deepen better on circular dependency.

  • As I said @Brunoderissosalvini this may be related to structure. If you look at the Django documentation, it suggests to do as I said. And I’ve never had problems like that. https://docs.djangoproject.com/en/1.8/ref/models/fields/#Django.db.models.Foreignkey But you should also evaluate your modeling because it may not be good.

2

Your error message is an indication of circular dependency. You wouldn’t happen to have, in emails/models.py, a line making:

from departamentos.models import Departamento

? That code worked before, because the app emails depended on departamentos, then when emails/models.py was loaded, she did the import, loaded the app departamentos entire, and then continued to read the content of the app emails.

When you did that departamentos raisin also depending on emails (by the way, what is causing the error is the import, not the creation of the field), so we have a problem:

  • Python starts to read departamentos/models.py; creates the module, empty;
  • He reads the line he asks to import emails.models; the module has not yet been read;
  • He starts to read emails/models.py; creates the module, empty;
  • He reads the line he asks to import departamentos.models; the module exists, but is empty;
  • He tries to read Departamento in the imported module; that name does not exist as the module is empty;
  • ImportError: cannot import name Departamento

Solving this is not easy, and it may involve refactoring your code (changing app templates). If you had certainty that the app emails to be loaded before the app departamentos, you could put the import not at the beginning of the file, but after the creation of the template GerenciarEmails:

emails/models.py

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

class GerenciarEmails(models.Model):
    ...

from departamentos.models import Departamento

... # Coisas que dependem de Departamento

Thus, the app emails would be read to the point where it defines GerenciarEmails, with the import app departamentos would be read in full (and she would have access to GerenciarEmails, since it has already been included in the module) and then the emails/models.py would continue your reading normally. It works, the hard thing is to ensure that reading order (if the departamentos was read first, it’s over, there’s no way to "fix" the order).

In the reply from Puam Dias it suggests specifying the foreign key using a string, rather than a direct reference to a model:

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

If you do this, no matter the app emails, can work (I can’t say, because I’ve never used this construction). If nothing else works, then all you have to do is move your templates from one app to another until there are no more circular dependencies between apps.

  • It does work, and it’s even good practice, but it’s also necessary for him to see his modeling as you indicated it. Maybe this isn’t cool.

  • @When I said "to work" I meant that I didn’t know whether or not, in the presence of a circular dependency, it would "break the dependency". You’d have to test to be sure.

  • No matter the emails app doesn’t work, python gives another error: departamentos.departamento: Reverse query name for field 'gerencia' clashes with field 'GerenciarEmails.departamento'. Add a related_name argument to the definition for 'gerencia'.

  • I’m seeing about your suggestion, and if it doesn’t work out too, I’ll dig deeper into that circular dependency, but I can see what she is.

  • @Brunoderissosalvini This error can be solved by placing a related_name in the field, as suggested. Do you know how it works? If you don’t know, ask a separate question and I’ll explain it better (too long to do in this cometary rsrs).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.