views:

140

answers:

2

Hello guys, I think this is more a python question than Django.

But basically I'm doing at Model A:

from myproject.modelb.models import ModelB

and at Model B:

from myproject.modela.models import ModelA

Result:

cannot import name ModelA

Am I doing something forbidden? Thanks

+6  A: 

A Python module is imported by executing it top to bottom in a new namespace. When module A imports module B, the evaluation of A.py is paused until module B is loaded. When module B then imports module A, it gets the partly-initialized namespace of module A -- in your case, it lacks the ModelA class because the import of myproject.modelb.models happens before the definition of that class.

In Django you can fix this by referring to a model by name instead of by class object. So, instead of saying

from myproject.modela.models import ModelA
class ModelB:
    a = models.ForeignKey(ModelA)

you would use (without the import):

class ModelB:
    a = models.ForeignKey('ModelA')
Thomas Wouters
Thanks a lot Thomas! Saved my day!By the way, I think the syntax for `a = models.ForeignKey('ModelA')` is `models.ForeignKey('module.model')`, that's how it worked for me!
Clash
+3  A: 

Mutual imports usually mean you've designed your models incorrectly.

When A depends on B, you should not have B also depending on A.

Break B into two parts.

B1 - depends on A.

B2 - does not depend on A.

A depends on B1. B1 depends on B2. Circularity removed.

S.Lott
Thanks for you answer! A person participates at max in one project, a project has only 1 leader. How do you remove the circularity from that?Person references a project. Project references it's leader (person)
Clash
@Clash: Many-to-many relationships do not require both sides to explicitly reference the other. You can do this in just one of the two. And. Why are they in separate modules?
S.Lott
S. Lott, it's not a many-to-many relationship, a person belongs to one project and a project has one leader
Clash
@Clash: Mutual relationships, like many-to-many, can be declared in just one place and will correctly reference the other. You do not need both to mutually include each other. **Why are they in separate modules?**
S.Lott
Oh, thank you S.Lott! That may be due because I missinterpreted the concept of modules... I thought project and person should be different modules, because they are different things
Clash
@Clash: Why did you think that? Can you provide a quote or a reference?
S.Lott
There is no quote or reference... it's because on Django tutorial, poll is separate module from the user, so I thought project would be a separate module from the user too
Clash