I've run into this problem a few times in different situations but my setup is the following:
I have two Django models files. One that contains User models and CouponCodes that a user can use to sign up for a Course. Those are both in the account/models.py file. Course and the related many-to-many field are in a different models file, course/models.py. I usually refer to these in my code as amod and cmod respectively.
In course/models.py I have an import statement:
from account import models as amod
class Course(ExtendedModel):
stuff = stuff
I need to import the account/models.py file for the many-to-many model/table between Course and User which is not shown here. So far, so good.
In the account/models.py file I have the CouponCode model. Each instance gets created and then can be assigned to a particular Course object after creation to allow a student to use it to sign up for a course in the system.
class CouponCode(ExtendedModel):
assigned_course = UniqueIDForeignKey("course.Course", blank=True, null=True, related_name='assigned_coupon_code_set')
...
...
@staticmethod
def assign_batch(c, upper_limit):
import course.models as cmod # Why is this allowed here?
assert isinstance(c, cmod.Course)
# Do other stuff here
That static method allows me to pass in a course object and a number of CouponCodes that I want to assign to it and then it will assign the next N number of unassigned codes to that course. My question arises from the assert statement.
I need to import the Course object from course/models.py in order to insure that the object being passed in is actually an instance of Course, but if I do that at the top of the file, I get problems because this file is already being imported into course/models.py. (amod is being imported into cmod and then in amod I need to import cmod).
Why does it allow me to do this if I import it in the method right before I need it versus at the top of the file?
Changing the name of the Working file different from the module which is imported in the script can avoid the Circular Imports problem. Import the module: Avoid importing objects or functions from a module that can cause Circular Imports. It is good to import the whole module to avoid the Circular Import.
Generally, the Python Circular Import problem occurs when you accidentally name your working file the same as the module name and those modules depend on each other. This way the python opens the same file which causes a circular loop and eventually throws an error.
It seems like the program file you have created is named threading.py , and you are importing a module also called threading . This causes a circular import because your file is shadowing the built-in module. Please rename your program (e.g., threading-example.py ). Save this answer.
When a module is imported (well, the first time it's imported in a given process), all the top-level statements are executed (remember that import
is an executable statement). So you cannot have module1 with an import module2
statement at the top-level and module2 with an import module1
at the top-level - it cannot obviously work.
Now if in module2 you move the import module1
statement within a function, this statement won't be executed before the function is actually called, so it won't prevent module1 from importing module2.
Note that this is still considered bad practice, most of the time a circular dependency means you should refactor your code to avoid the problem (extract the parts both modules depends on into a third module that depends from both but none of the others depends on, or simply merge the modules) - but some cases are complex due to other constraints so having this as a last-resort solution is fine.
Also, you do not need to import a model to reference it in a ForeignKey
or Many2Many
field - you can pass a "appname.ModelName"
string, cf https://docs.djangoproject.com/en/1.8/ref/models/fields/#foreignkey
To refer to models defined in another application, you can explicitly specify a model with the full application label. For example, if the Manufacturer model above is defined in another application called production, you’d need to use:
class Car(models.Model): manufacturer = models.ForeignKey('production.Manufacturer')
This sort of reference can be useful when resolving circular import dependencies between two applications.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With