Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 337
rich Avatar asked Dec 10 '22 09:12

rich


2 Answers

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.

like image 144
Gabriel Hurley Avatar answered Jan 31 '23 00:01

Gabriel Hurley


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

like image 37
dting Avatar answered Jan 31 '23 00:01

dting