I am having problems importing models between my apps in my current django project. When trying to run the dev server or sync the database, I receive the error:
File "/path/to/Project/../Project/app1/models.py", line 3, in <module>
class SomeModel(Thing):
NameError: name 'Thing' is not defined
Thing is defined in Project/main/models.py which I import into Project/app1/models.py via:
from project.main.models import Thing
I am aware that this sort of thing can be the result of python preventing circular imports.
Currently I have three django apps: main, app1, app2
The imports for each app are like so:
main:
from project.app1.models import AnotherThing
app1:
from project.main.models import Thing
app2:
from project.main.models import Thing
from project.app1 import Something
I suspect that importing models from app1 into app2 is causing the problem, since both of those apps import models from main, which in turn imports models from app1, etc.
If this is the case - what other methods can I use to achieve the same effect as these imports?
Is there a more accepted way of organizing things so that I won't run into this?
If you want to subclass those models, you need to remove circular dependency. Refactor common stuff into another module, and make those two import that instead of each other. If the model is only used as a foreign key, you can use string instead of an object to defer the import (e.g. ForeignKey('app.Model') — see documentation for details).
Related
I have a utils.py file in an app directory at the same level as models.py. I am trying to import a class (a model) in utils.py:
from models import TeamConstraint
My IDE does not report any conflict, however when running the server I am getting an ImportError:
ImportError: cannot import name TeamConstraint
I tried checking for circular dependencies, there is a file tasks.py also in the same level as the rest that imports from utils.py:
from scheduler.utils import current_indie_teams, matchcount_by_week
Although I don't understand why here scheduler needs to be included explicitly, while when trying to import a model it is not required (or so says PyCharm at least).
I am trying to figure out how to solve this.
When you say from models import TeamConstraint it's not clear what models is.
It could be a different app with the name models or it could be the file in the same folder. It's better to be explicit than implicit.
Try using an absolute import from scheduler.models import TeamConstraint or if you really want to use a relative import do so as such from .models import TeamConstraint (Notice the . before models)
Also it seems like you are using Python3 but your PyCharm is configured for Python2, else it would warn you.
whenever you get import errors, try delaying one of the imports.
here place 'from models import TeamConstraint' in class or function instead.
I've got two Django apps that will end up sharing a lot of code (both reference an external API and do data manipulation on what that API returns). I'm trying to find out how to properly share code between the two apps.
So far I've been trying to have a third app that's imported by the first two, so my file structure looks something like this:
\MyProject
\app1
__init__.py
views.py
\app2
__init__.py
views.py
\common
__init__.py
myCommonCode.py
But when I try the following from app1 or app2 I don't see myCommonCode.py
import common
print dir(common)
All three apps are included in my INSTALLED_APPS in my settings.py.
I am certain there's something simple I'm missing, I just can't seem to find out what it is. To clarify, I am NOT trying to share the same model at this point, but the same python code for reaching out to an external API.
You don't see a sub-module if you import a package. You have to import it in the
__init__.py or directly:
from common import myCommonCode
I have a Pyramid app, I split models AND views into separate files in following manner:
How do I split models.py into different files for different models in Pyramid?
One small consequence for views is that since I have them in separate view files in a "views" package is that they cannot find models.py, now models package, since it resides in parent directory.
That is, it used to be:
models.py
views.py
Now it's:
views/__init__.py
views/view1.py
views/view2.py
models/__init__.py
models/model1.py
models/model2.py
Therefore, importing from models in a view results in:
from models import (
ImportError: No module named models
Now, I can work around this by adding following path search module extension in views/__init__.py:
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
But that's kind of kludgy. Is there a better, maybe Pyramid-specific solution?
This is not really pyramid specific, it is just python.
See https://docs.python.org/2/tutorial/modules.html#packages
for a detailed explanation.
You want to
import models.model1
Or
from models.model2 import (...)
I'm late, but it can help some other person.
For solve this, you need to specify your project name. In your case, if the project name is projet_name import your models like this.
from project_name.models.model1 import *
or
import project_name.models.model1
I suppose is not the best way, but it work fine for me.
How can I import all models in the settings.py in INSTALLED_APPS? When i`m trying to insert some model there is an error occurred: "no models named app1_model"
-ProjectName
--ProjectName
---models
----__init__.py
----admin.py
----app_1_model
----....
----app_n_model
---templates
---__init__.py
---settings.py
---urls.py
---wsgi.py
--manage.py
^ Structure of project ^
The INSTALLED_APPS is for apps not for models. Models are classes that live within your app, usually in /«app_name»/models.py.
I think you have misunderstood how a Django project is structured. Try working through a tutorial example.
a typical structure:
/«project»/«app_name»/models.py
and in settings:
INSTALLED_APPS = [ ... '«app_name»' ... ]
Your path will contain the base project directory, so you can import your app where you need it.
And to use them:
from «app_name».models import *
Although it is always best not to import *, instead, name the classes you wish to import.
To answer the question in the comment:
If you don't like the idea of storing all your models in one file (even though it is normal to do this), you can create a module called models. To do this, create a directory called /«project»/«app_name»/models, inside it put __init__.py (to declare it as a module) and then create your files inside there. You then need to import your file contents into the module in __init__.py. You should read about Python modules to understand this.
To answer the second comment question:
To view models in admin, you should create an admin file with model admin objects.
And finally:
Please read through the tutorials to ensure you have a thorough understanding of Django. Otherwise you're wasting your own time!
I'd like to move my models to a separate directory, similar to the way it's done with Rails to cut down on code clutter. Is there any way to do this easily?
Thanks,
Collin
I assume you're using the basic webkit and not Django or something fancy. In that case just create a subdirectory called models. Put any python files you use for your models in here. Create also one blank file in this folder called __init__.py.
Then in your main.py or "controller" or what have you, put:
import models
at the top.
You just created a python package.
Brandon's answer is what I do. Furthermore, I rather like Rails's custom of one model per file. I don't stick to it completely but that is my basic pattern, especially since Python tends to encourage more-but-simpler lines of code than Ruby.
So what I do is I make models a package too:
models/
models/__init__.py
models/user.py
models/item.py
models/blog_post.py
In the main .py files I put my basic class definition, plus perhaps some helper functions (Python's module system makes it much safer to keep quickie helper functions coupled to the class definition). And my __init__.py stitches them all together:
"""The application models"""
from user import User
from item import Item
from blog_post import BlogPost
It's slightly redundant but I have lots of control of the namespace.