On Thu, 2006-10-19 at 05:27 -0700, MerMer wrote: > Malcom, many thanks. > > I have to admit as a newbie to Python and Django and I dont' fully > understand how "import" works. I just presumed that you put a > reference to any module at the top.
You can. But you aren't referring to a module, you are referring to something inside the module's namespace (the Review model object). The difference is important. > At the top of the product.models.py file I have the following:- > > "from mysite.promotions.signals import update_review_average" Welcome to the world of recursive imports. The quick fix here is to replace that line with from mysite.promotions import signals and you will be fine. To understand what is happening (this is more comp.lang.python territory, but one post won't hurt), think about what is happening at the Python level here: Step #1: Python imports your models file. It opens the file, makes a note that it is about to create a new module called "product.models" and then starts reading the file one line at a time. It does this by putting an entry in the sys.modules dictionary with the key as the name of the module and the value being an empty module object, which it will then fill in as it parses the file. Step #2: very early on in the models file it finds a line to import some stuff from signals. Step #3: Python stops processing products.models and starts importing signals. it opens up the signals.py file, makes a note that it is creating a new module (another entry in sys.modules) and starts reading it one line at a time. Step #4: It encounters the line in signals.py that says "import some stuff from models.py". Now the fun begins. Python looks in its dictionary of modules (sys.modules) and sees an entry for product.models already (it has this entry do that it doesn't get stuck in loops or try to import a module more than once). However, this product.models entry points to a currently empty module (since Python has not yet finished importing it in step #2 -- you told it to go off and process signals first). Because you want something very specific from models.py, Python raises an error (that very specific thing ("Review") does not exist in the empty model. Now, you can work around this by either (a) not having circular imports (they often suggest a much tighter coupling than you intended in any case), or (b) only importing the module name, not a specific thing from that module. If you had "from product import models" in signals.py, then in step #4, above, Python would see that it had already imported (or started to import) product.models and continue on happily. Later, after everything had finished importing, you could refer to models.Review inside signals.py and it would work (because the "models" module would be fully imported). You could not refer to models.Review outside of a function in signals.py, because you would hit the circular import problem again, but inside functions (which aren't executed until you call them -- well after import time), you could be fine. Note that this is not a problem with Django. It is a fairly natural consequence of using a language that allows dynamic imports and name bindings (e.g. Python) and only wants to import things once at most. It would be possible for Python to work around this problem in some cases, but not always, in general. Once you understand the import process outlined above, it is usually fairly easy to work out how to avoid such import problems. Regards, Malcolm --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users -~----------~----~----~----~------~----~------~--~---