I have a Django project with the following structure
project/
package1/
__init__.py
api.py
views.py
package2/
__init__.py
api.py
views.py
__init__.py
urls.py
wsgi.py
In package1/api.py I perform the following import:
from .views import my_func
When I do this, the __name__ value in my package1/views.py module is project.package1.views, this is exactly what I want.
However when I do the same thing in package2/api.py:
from .views import my_func2
I get package2.views for __name__, it's missing the project prefix.
I can fix this by using the full from project.package2.views path, but I don't understand why it would work for one package but not another.
I don't have anything at all in my __init__ files that would alter how the imports work, either.
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.
ı 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.
I have a pre-existing Flask application which is becoming quite large, so I've decided to switch to using blueprints, following the Flask documentation, to organise my views.
Most of my views share functions and decorators. When all my views were in one file, it was easy to access them. How now all the views are organised into separate files, I'm unsure where to locate information such as functions and views.
I have the following file structure:
run.py
website/
__init__.py
views/
__init__.py
admin.py
home.py
...
templates/
static/
So, where do I locate functions and decorators and how do I access them? Thanks.
Any code that is shared by two or more blueprints can be put in separate modules. So for example, you can have decorators.py and functions.py, which can be located inside your views directory:
run.py
website/
__init__.py
views/
__init__.py
decorators.py # <-- common code
functions.py # <-- common code
admin.py
home.py
...
templates/
static/
Then in your views you can import elements from these as follows:
from .decorators import my_decorator
If there's other code in other directories besides views that might need these common elements (such as a forms directory for Flask-WTF forms, for example), then you can put your common modules one level up in website.
run.py
website/
__init__.py
decorators.py # <-- common code
functions.py # <-- common code
views/
__init__.py
admin.py
home.py
...
templates/
static/
And with this structure you can import from your views as follows:
from ..decorators import my_decorator
or:
from website.decorators import my_decorator
You can see an example of the above structure in the Flasky application that is featured in my Flask Web Development book. I have decorators.py, email.py and exceptions.py as common modules that can be accessed by all the blueprints.
If the number of common modules is large, you can also move the common modules inside their own package:
run.py
website/
__init__.py
common/
__init__.py
decorators.py
functions.py
views/
__init__.py
admin.py
home.py
...
templates/
static/
And then the imports look like this:
from ..common.decorators import my_decorator
or:
from website.common.decorators import my_decorator
I've been trying to follow django tutorials and get started with python for the past few days, but I keep getting stuck at the same point in each one and can't seem to find a solution.
I have a directory that represents a django 'app', in this case called rango.
Inside of rango I have a views.py file and a urls.py file. I also have __init__.py in the same folder, so my directory looks like this:
rango
│
├── __init__.py
├── views.py
└── urls.py
Now when I add:
from rango import views
to the urls.py file I get an error 'No module named rango'
I read a bunch of other questions and people suggested adding
import sys
sys.path.append(".")
but that didn't change anything. Still getting the same error.
Anyone have any idea what could be going on?
Using python 2.7 on windows
Consider using a relative import.
In urls.py:
from . import views
In __init__.py:
__package__ = 'rango'