Test failure because model couldn't be imported - django

Application I am working on is proprietary and thus I will try to provide as much information as possible.
When running python manage.py test, which runs all the tests, only one application among many others fails. Too many hours have been burned on this.
The output is:
ImportError: Failed to import test module: app.aom.apps.forum.tests
after this, tracing is listed and then one line which says that the problem occurs when importing models into tests.py file, that is:
from .models import ForumSectionGroup, ForumSection, ForumThread, ForumPost
and the last line of the output is:
RuntimeError: Model class app.aom.apps.forum.models.ForumSectionGroup doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
I have Googled and researched what could cause this problem, and the conclusion: either I am importing module before application is loaded or I don't have the application listed in INSTALLED_APPS. But none of these seems to be the problem. Maybe testing mechanism somehow skips few steps and renders the model unloaded before importing it.
Explicitly assigning app_label as part of class Meta in the model results in conflict, because the model ends up registered twice, when I force it. I was driven to this conclusion by looking at the code at line 111, https://github.com/django/django/blob/master/django/db/models/base.py

I ran into this same issue. For me what fixed it was changing
from .models import Model1, Model2
to
from app.models import Model1, Model2
The from .model import syntax works fine in view.py, etc. but in the tests it was not working. This only seems to be the case when using a non-standard structure as pointed out in a comment above.
In my specific case I was using Django 1.11.

Related

Moving from Django 1.6.x to 1.9.x import model errors

I have a few defined apps in my Django project, each with their own sub-directory (created with startapp)
In the views.py of app1 I have an import to a model from app2
from app2.models import MyModel
This worked in Django 1.6.x. In version 1.9 I get:
Could not resolve variable
sometimes on MyModel, sometimes on the filter(..) method, or on both.
If I change the import to
from app2.models import * ##UnusedWildImport
then everything works just fine.
Has anything changed in 1.9.x (or before) that requires a different mode of importing models external to the app?
I think I can rule our circular import problems as this would have failed in 1.6...
Edit: Based on the comments I started wondering whether this might be a PyDev problem.
I tried:
Removing and re-adding Python to PyDev - it did not help
This https://stackoverflow.com/a/8534599/5958359 - removing the myproject/src folder from PYTHONPATH worked ... with a caveat.
The error did not appear when I completely removed the import statement, so this is not a good solution
This is a PyDev error.
Searches haven't yielded an adequate solution - most simply explain how to disable the error - so I will not link to any solution here.
My workaround, as much as I don't like from xxx import * seems like the best temporary solution.

django get_model returns null when called from __.init__.py?

from django.db.models import get_model
modelname=get_model('base','reports')
The above code works fine in views.py and django shell,but returns null when called from init.py
folder structure is shown below
projectsfolder
--base
----models.py
----views.py
---- init.py
That can't possibly work. Anything in __init__.py is always going to be executed the first time anything in that directory is imported. But Django has to import the models in order to register them, so you've got into a chicken-and-egg situation: it won't register them until it imports them, but you're trying to get the models when they're imported...
Can you explain though why you don't simply do from models import Reports?
I still don't know why my code above doesn't work only # __init__.py.But the code below worked for me.
modelname=get_model('base', k['tablename'], seed_cache=False, only_installed=False).
Also django fixtures is a better way to initialise db. :):)

Extending imagestore models

I'm trying to install imagestore app in my project. Default models are created succefully, and all other parts working properly.
But, it have a feature to extend base (abstract) models and create your own by some complicated mechanism. This is mine model:
from django.db import models
from imagestore.models.bases.album import BaseAlbum
class Newalbum(BaseAlbum):
title = models.CharField("title", max_length=128)
class Meta(BaseAlbum.Meta):
app_label = "imagestore"
abstract = False
Also I have a string IMAGESTORE_ALBUM_MODEL = 'art.models.Newalbum' in my settings.
When I run syncdb it tells me Backend module "art.models" does not define a "Newalbum" class. ('module' object has no attribute 'Newalbum').
But of course it defined.
And the strangeness is only begins. When I put debug statement in the place where imagestore trying to get my model it prints proper module (already imported) and proper class name (string). But! dir(mod) prints only variables appeared before "from imagestore.models.bases.album import BaseAlbum" .In above example only "models" and default underscored attributes. Why? What I don't know about importing modules?
I already tried to install it in many awkward combinations of settings properties, versions of django (and required apps), app_label and so on. It creates tables, when I doesn't add IMAGESTORE_ALBUM_MODEL in my settings, but this models hasn't any BaseClass' behaviour.
So, what I'm doing wrong?
Solved it! While stepping through the import process (I added the following to imagestore.utils.load_class)
import pdb
pdb.set_trace()
I found that there is a circular import. Here's the order of things (slightly simplified):
load_class(IMAGESTORE_ALBUM_MODEL)
from imagestore.models.bases.album import BaseAlbum
BaseAlbum has an FK to IMAGESTORE_IMAGE_MODEL (head), so it gets imported with load_class
load_class(IMAGESTORE_IMAGE_MODEL)
from imagestore.models.bases.image import BaseImage
BaseImage has an FK to IMAGESTORE_ALBUM_MODEL (album), so it gets imported with load_class
When this calls __import__ IMAGESTORE_ALBUM_MODEL is already in sys.modules, though incomplete because it's still being built. And thus the module doesn't have an "Album" attribute yet.
The quick solution is to move the head field to models.album.Album and remove it from BaseAlbum. After doing this I was able to get the site running again. You must use the models package in your new app (not a simple models.py), with Image and Album in separate files.
If this isn't clear enough, drop me a line and I'll try to do better.

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
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:
Move around your classes and imports so that the imports only go one direction.
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')
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.
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
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.

Django: import error that refer to template tags

I'm having a headache with some errors that appear suddenly on an application I'm developing. One time I solved it using complete imports (including the project dir) but this time the error has no sense.
TemplateSyntaxError at /accounts/login/
Caught ViewDoesNotExist while rendering: Could not import e_cidadania.apps.proposals.views. Error was: cannot import name User
And marked code is:
{% trans "Lost your password?" %}
The import line at views.py:24
from django.contrib.auth.models import User
I must say, 24h before everything was working fine and no changes were made to the repo.
I've looked the url and the view, both are fine. I've run manage.py shell and tested the import, works fine. I did put some markers in the code to test how it was running and the program crashes exactly importing the User model in that file (there are lots of imports User in the application and not one of them gave a warning). Even deleting the import from thefile gives the same error!
How can I track this to know what is the real problem?
UPDATE: I forgot to mention that the marked error is in the userprofile module, and the proper error is given in the proposals module, a module that has absolutely nothing to do with userprofile.
UPDATE 2: You can see the code here, the application is GPL so there is no problem.
The "relation" between userprofile and proposals modules is that you probably refer to both in the urls definition, which is used to do the reverse when using {% url 'whatever.viewname' [args] %} there probably you do import some view function from both.
I would start having a look at modules you're importing there.
I had this annoying problem (more than once) and most of the time it was caused by recursive imports or by a order dependent imports that I was not aware of (because most of the times "was working").