I've searched for this problem and tried different solutions but can't fix it.
In my Django project I have different apps and a non-app directory called 'testing_utils' with modules which serve for a testing purposes. In particular I want to import all available models to file dummy_factory.py. However when I simply import modules from my apps like so:
from abc import ABC
from datetime import date
from users.models import User
I get the error message
ModuleNotFoundError: No module named 'users'
Which is strange since I definetley can import models to some_app.views.py and access them.
Here's an example of my project's directory:
/home/user/dev/project/
▸ project/
▾ testing_utils/
dummy_factory.py
▾ users/
▸ __pycache__/
▸ migrations/
▸ templates/
▸ tests/
__init__.py
admin.py
apps.py
models.py
views.py
manage.py*
/home/user/dev/project/ needs to be in your PYTHONPATH to be able to be imported.
If your testing_utils is meant to be local only, the easiest way to accomplish this is to add:
import sys
sys.path.append('/home/user/dev/project/')
... in dummy_factory.py before importing the module.
Solutions that would be more proper would be to install users (how exactly you'd make your package installable depends on your system and what version of Python and Pip you need to support), or to use a virtualenv that automatically adds the right directories to PYTHONPATH.
Related
I am working on a Django app in which I want to import some class/function from generator.py into my views.py to process an user-submitted input. My folder structure looks like this:
project/
models/
__init__.py
generator.py
web/
django/
__init__.py
settings.py
urls.py
wsgi.py
django_app
__init__.py
views.py
etc.
Inside views.py, I have
from ...models.generator import Generator
When I try to run server, what I get is:
ValueError: attempted relative import beyond top-level package
I've seen many answers, but most are about manipulating sys.path or changing PYTHONPATH. I'm not sure how and where to do either cause I'm rather new to Django.
Can someone tell me exactly which commands to run to allow the import to be done?
Import of python is based on sys.path and cannot be outside the top-level dir. More information.
That's mean, if you append top of BASE_DIR path in sys.path you can import. But it's a tricky way.
def import_function():
import sys
sys.path.append(os.path.dirname(BASE_DIR))
module = __import__('models.generator') # import code
sys.path.pop()
return module
g_module = import_function()
g_module.Generator
I have a Django project (Python 2.7.15) with the following structure:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
utils.py
utils/
__init__.py
filters.py
In my utils/filters.py file I have a class MyFilter. From polls/admin.py, however, when I try to run from utils.filters import MyFilter, I get ImportError: No module named filters. How can I import my custom filter inside the polls app without renaming the polls/utils.py module or the utils package?
NOTE: This it's not a circular import problem. This happens even if I don't import anything from utils/filters.py. It's a name conflict between utils/ and polls/utils.py. Python tries to find filters.MyFilter inside polls/utils.py and it doesn't find it so it throws the error. I just want to figure out a way to bypass this conflict and force python to look for filters.MyFilter inside the utils/ package in the project root.
In Python 2, import utils is ambiguous because it can be a relative or an absolute import.
If you enable the Python 3 behaviour by adding the following import to the top of your module,
from __future__ import absolute_import
then from utils.filters import MyFilter will be treated as an absolute import and will work.
Once you have added the future import, you would need to use an explicit relative import import .utils if you wanted to import polls/utils.py from polls/admin.py.
I just started testing out PyCharm on my existing Django project, and it doesn't recognize any imports from apps within my project:
in my_app1/models.py:
from my_app2.models import thing
"Unresolved reference 'my_app2'"
Why is this? My project's directory structure matches the recommended layout, and it runs without errors, it's just PyCharm's magic doesn't want to work on it.
It seems related to this question:
Import app in django project
But I can't figure out what I am doing wrong. If I try:
from ..my_app2.models import thing
The PyCharm error goes away and it can auto predict, etc. But when I run the project Django throws:
ValueError: attempted relative import beyond top-level package
EDIT:
Project structure:
my_project/
src/
manage.py
db.sqlite3
my_app1/
templates/
__init.py__
admin.py
models.py
urls.py
views.py
...
my_app2/
templates/
__init.py__
admin.py
models.py
urls.py
views.py
...
my_project_app/
settings/
__init.py__
urls.py
...
I was having this issue using a "2 Scoops of Django" project layout, e.g.
/project_root
/project_dir
/config
/settings
/my_app
/tests
models.py
/requirements
readme.rst
The code was working, but in /tests, IntelliJ/PyCharm showed an unresolved reference:
from my_app.models import Something
I had all the __init__.py files in place. I ended up having to set the sources root to project_dir:
Right-click on project_dir, Mark Directory as > Sources Root
Now that I can take a look over you project structure I can tell you that the problem appears to be related to a missing __init__.py in your 'src' folder. Try adding an empty file named __init__.py in the root of 'src' folder.
Also, take a look to this question, I think is the same problem or a very similar one.
Hope this could be useful, cheers!
I was having this issue after I change my environment to virtualenv, so I changed my python interpreter to my current virtualenv.
Go to File > Settings > Project Interpreter.
In that window you would be able to see all packages includes on this interpreter, Django should be there.
This worked for me.
Link about: https://intellij-support.jetbrains.com/hc/en-us/community/posts/206598665-Unresolved-Reference-Errors-for-django
ı have a django project and i need to access some of models in my folder that under the django main project folder.Let me illustrate this.
src\
main\
urls.py
models.py
view.py
lib\
__init__.py
helper.py
This is the example folder structure and i need to import some class of main app's models inside the helper.py.I tried these:
from main.models import exampleClass
from ..main.models import exampleClass
And i also tried adding a __init__.py file in the main project folder:
src\
...
main\
lib\
__init__.py
Always errors 2 kind :
1)ValueError : relative import error
2) no module name..
I need the solution and need good explanation why i failed always.Thank you so much guys.
Add __init__.py in main folder instead of src folder. Then try to import using from main.models import exampleClass. It should be working.
You don't need .. if main and lib are both django's apps, and you have registered them in INSTALLED_APPS settings.
If main and lib are in the same level that manage.py:
src/
main/
...
lib/
...
manage.py
...
You just need:
from main.models import exampleClass
How did you set $PYTHONPATH variable ? The search paths are relative to this environment variable.
So if you want to specify a path like main.models, it should contain the src directory.
Note that you can also manage it with the sys.path array.
Django normally add all the applications to sys.path. You may try to print it inside the settings.py file to have an idea.
To add a path from the settings.py file of the project, you could do something like:
import os.path
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(os.path.join(BASE_DIR, "../lib"))
If for example you have a lib directory at the same level as the directory that contains the settings.py file.
My project contains three Python applications. Application 1 is a web app. Applications 2 and 3 contain scripts downloading some data.
All three apps need to use a module Common containing a "model" (classes that are saved to database) and common settings.
I have no clue how to structure this project. I could create three directories, one for each application, and copy Common three times into their directories (doesn't seem right).
Another idea that comes to mind is; create a main directory and put there all files from Common, including __init__.py. Then, crete three subdirectories (submodules), one for each application.
Another way would be installing Common using pip, but that means I would have to reinstall every time I change something in that module.
In previous projects I used .NET - the equivalent in that world would be a Solution with four projects, one of them being Common.
Any suggestions?
I have a similar project that is set up like this
project_root/
App1/
__init__.py
FlaskControlPanel/
app.py
static/
templates/
models/
__init__.py
mymodels.py
Then, I run everything from project_root. I have a small script (either batch or shell depending on my environment) that sets PYTHONPATH=. so that imports work correctly. This is done because I usually develop using PyCharm, where the imports "just work", but when I deploy the final product the path doesn't match what it did in my IDE.
Once the PYTHONPATH is set to include everything from your project root, you can do standard imports.
For example, from my FlaskControlPanel app.py, I have this line:
from models.mymodels import Model1, Model2, Model3
From the App1 __init__.py I have the exact same import statement:
from models.mymodels import Model1, Model2, Model3
I can start the Flask application by running this from my command line (in Windows) while I am in the project_root directory:
setlocal
SET PYTHONPATH=.
python FlaskControlPanel\app.py
The setlocal is used to ensure the PYTHONPATH is only modified for this session.
I like this approach
projects/
__init__.py
project1/
__init__.py
project2/
__init__.py
lib1/
__init__.py
libfile.py
lib2/
__init__.py
So, I need to cd into the projects folder.
To start a projects use
python -m project_name
This allows me to easily import from any external lib like
from lib1.libfile import [imoprt what you want]
or
from lib1 import libfile
Make standard Python modules from your apps. I recommend structure like this:
apps/
common/
setup.py
common/
__init__.py
models.py
app1/
setup.py
app1/
__init__.py
models.py
project/
requirements.txt
Basic setup.py for app common:
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(
name='common',
version='1.0.0',
packages=find_packages(),
zip_safe=False,
)
Make similar setup.py for other apps.
Set editable "-e" option for your apps in requirements.txt:
-e apps/common
-e apps/app1
Install requirements with pip:
$ pip install -r requirements.txt
Editable option means that source files will be linked into Python enviroment. Any change in source files of your apps will have immediate effect without reinstalling them.
Now you can import models from your common app (or any other app) anywhere (in other apps, project files, ...).
I would create a structure like this:
project_root/
app1/
__init__.py
script.py
common/
__init__.py
models.py (all "common" models)
app1/script.py
import os, sys
# add parent directory to pythonpath
basepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
if basepath not in sys.path:
sys.path.append(basepath)
from common.models VeryCommonModel
print VeryCommonModel
If you don't want to set the python path at runtime, set the python path before running the script:
$ export PYTHONPATH=$PYTHONPATH:/path/to/project_root
And then you can do:
python app1/script.py