rich
rich

Reputation: 605

Django import error from foreign key in another application model

I followed this post here and sorted out how to set the ForeignKey of one model to a model in another application. However, when I try it a second time I get an error and not sure why.

I have Central app with models for a 'project' and an 'annotation', and a Reports app with a report model. An 'annotation' has a FK to a 'report' in the Reports app, and that seems to work fine with this code:

#models.py for Central app
from GIanno.pt_reports.models import Report

class annotation(models.Model):
    ... 
    report=models.ForeignKey(Report)

But, in the Reports app, when I try to set a FK for the 'report' to link it to a 'project' from the 'Central' app using the same format as above, I get an error "cannot import name 'project' from the import line.

Any ideas on why it works one way and not the other. Does order somehow matter? Thanks

Upvotes: 4

Views: 6815

Answers (3)

renderbox
renderbox

Reputation: 1655

Another scenario where the Lazy Relationships might be useful is with import order. It's not a circular reference (where it can't tell who's first) but a case where one piece of code is loaded before the other can be.

For example, let's say I have a Doc Model and a Log Model. The Log model has a FK for the Doc so I can record changes in the document. This works fine until, let's say, I try to generate a Log record in my save method for my Doc model (to make a save event log entry). There is no Log PK in the Doc object in this case but is a similar issue.

In this case you get an import order problem, where one will try to reference something that has not been loaded into Python yet. It's similar to a Circular Reference but a different cause.

This can be solved other ways but is another example where you will run into this problem.

Upvotes: 0

Gabriel Hurley
Gabriel Hurley

Reputation: 40082

My guess is that you have created a circular import condition. This occurs when you import something from one python module which in turns imports from the module which is trying to import it, thus preventing the import from ever resolving.

In general there are three strategies for dealing with circular imports, two of which will work in this case:

  1. Move around your classes and imports so that the imports only go one direction.

  2. Use lazy evaluation. In Django's case this can be accomplished for a ForeignKey by passing a string specifying the app name and model using dot notation: report=models.ForeignKey('central.Report')

  3. Move the import statement out of the global module scope and into the scope of a function within the module. That way the import isn't evaluated immediately and the module can be successfully imported as a whole while still allowing the import within the module to happen when it's called. (Note: this won't work for ForeignKey relationships)

The lazy FK resolution (#2) is probably your best bet here. In general, though the best strategy is to simplify your model/module arrangement to avoid circular imports whenever possible.

Upvotes: 13

dting
dting

Reputation: 39307

Try:

class annotation(models.Model):
    ... 
    report=models.ForeignKey('centralapp.Report')

Replace 'centralapp' with name of your central app name without needing to import.

Lazy Relationships

Upvotes: 1

Related Questions