Django sys.path.append for project *and* app needed under WSGI - django

Could somebody give me a pointer on why I need to add my project root path to the python path as well as the application itself in my WSGI file?
Project base is called 'djapp', the application is called 'myapp'.
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..')
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../djapp')
os.environ['DJANGO_SETTINGS_MODULE'] = 'djapp.settings'
If I omit the line with "/../djapp/" the log tells my that 'myapp' can not be imported, even though 'djapp.settings' is. (validating 'djapp' was imported)
It al runs properly with the ./manage.py command. there's a __init__ in the project folder.
For testings sake, I see the same issue using addsitedir:
site.addsitedir('/home/user/web/project/')
site.addsitedir('/home/user/web/project/djapp')

Since djapp (the django project folder) is in a parent folder that also belongs to the deployment I renamed the djapp folder simply to project.
Then this code is always correct:
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..' )
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../project')
os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings'
The complete folder layout being:
host.example.com\
etc\
bin\
project\
logs\
And what have you. This way project can always be called project :)
Hope that helps.
GrtzG

Presumably you've got code within your project which is doing from myapp import foo.
Two options:
change that to from djapp.myapp import foo, which is not recommended as it prevents portability;
only add djapp in your WSGI, and set the DJANGO_SETTINGS_MODULE to just 'settings'.

Related

ModuleNotFoundError: No module named 'config.wsgi'

I'm trying to run a .py file and in the file I have this import
from config.wsgi import *
import os
from django.template.loader import get_template
from weasyprint import HTML, CSS
from config import settings
The whole project works, if I set runserver, the project starts without any problem, but this file does not work. The structure of the project is as follows
NombreDelProyecto
--app
---config
----__init__.py
----asgi.py
----settings.py
----wsgy.py
----db.py
---core
----general
----login
----user
----archivodetest.py
the case as I say the project works, but in the views of the applications that I have been doing to put imports I get in red underlined but as I say it works for example:
from core.general.forms import ActividadForm
That comes out in red, if I put in front of the core, app.core as follows
from app.core.general.forms import ActividadForm
it does not show red but the project does not work and I get the following error
from app.core.general.forms import ActividadForm
ModuleNotFoundError: No module named 'app'
I understand that it is the routes or something I did wrong from the beginning, please could someone help me.
Thank you very much.
I tried adding the route, changing the app's route in settings, but to no avail.
You've named the file wsgy.py but it needs to be wsgi.py.
Rename your file in config and retry.
To your question, I think its because you're missing the __init__.py file in the general app.
If you haven't already go one, you'll likely need to have add the same again in your core app too.
You probably manually created all of these files and structures I suspect, and if that's the case, please take a look at the documentation regarding creating new apps inside a django project.
If you go a bit further up the page, it will also tell you how to create the initial django project structure with a command.
Thank you very much for the answer, I managed to solve it after a lot of testing.
There are two ways, open the project again from the app folder (I had it open in the ProjectName folder).
Or as a second option in pyCharm on the left where the project folders are, I went to the app folder (which is the root) and right clicked and in the menu, Mark Directorie as - Sources root. Then my problem is fixed.
I had all the arcvhiso init.py, and where I put the wrong name wsgi.py is that I wrote it wrong here but in the project it was right.
Thank you very much for the help.

How to run django.setup() properly from within a stand-alone python file inside of a django app (on linux-ubuntu)?

Im trying to run a stand-alone python file in a django project. The problematic code is below (standalone.py):
import os
import django
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") tried as well
os.environ["DJANGO_SETTINGS_MODULE"] = "myproject.settings"
django.setup()
The error i receive is: 'No module named myproject.settings'. Somehow the project settings file is not being recognized.
The file runs just fine on my local machine however the problem occurs when running the file on a linux-ubuntu server.
This file is being run from within an app: myproject>myapp>standalone.py
When i move this file to the same directory that myproject resides in, the file runs just fine, so im assuming that the myproject.settings module is not being recognized from within the app directory.
As a temp fix:
sys.path.append('path_to_myproject/')
seems to resolve the issue, but definitely not something i want in production code. Any suggestions on how to resolve this issue? Thanks in advance
If the settings module is myproject.settings, then the outer myproject directory must be on the python path. If the script is in the outer myproject directory (the one that contains manage.py) then you don't need to do anything because the current directory is on the path. Otherwise, you have to manually add the directory to the python path.
The way to add something to the python path is sys.path.append(), so you can't avoid having that in production code (unless you use the PYTHONPATH environment variable instead). Perhaps you would be happier with adding the parent directory instead of hardcoding the path.
sys.path.append('..')

Easily rename Django project

Is there an easy way to rename a project? I tried to rename the folder, but it didn't work.
Renaming the project is actually easier than renaming an app. This question explains how to rename an app.
To rename the project, you need to change the project name wherever it appears. grep -nir oldname . can help you find where it appears. In my case, I had to change the following places:
Rename the oldprojectname directory to newprojectname
manage.py: Change os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'oldprojectname.settings')
newprojectname/wsgi.py: Change os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'oldprojectname.settings')
newprojectname/settings.py: Change ROOT_URLCONF = 'oldprojectname.urls' and change WSGI_APPLICATION = 'oldprojectname.wsgi.application'
newprojectname/urls.py: Change oldprojectname in a line I had added
very simple and efficient
add this command to any app in your project like this ,
# app/management/commands/renameproject.py
import os
import glob
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
help = 'Renames the Project'
def add_arguments(self, parser):
parser.add_argument('old', nargs='+', type=str, help="current project name")
parser.add_argument('new', nargs='+', type=str, help="new project name")
def handle(self, *args, **options):
old = options["old"][0]
new = options["new"][0]
base = str(settings.BASE_DIR)
projectfiles = []
managefile = os.path.join(base, "manage.py")
projectfiles.append(managefile)
projectfiles += glob.glob(os.path.join(base, old, "*.py"))
projectfiles += glob.glob(os.path.join(base, old, "**", "*.py"))
for pythonfile in projectfiles:
with open(pythonfile, 'r') as file:
filedata = file.read()
filedata = filedata.replace(old, new)
with open(pythonfile, 'w') as file:
file.write(filedata)
os.rename(os.path.join(base, old), os.path.join(base, new))
Now just run this command
python manage.py renameproject oldname newname
have fun 😎
How it works:
Searches .py files across the project and replaces the old name with
new.
To rename a Django project, you need to change the project name wherever it appears.
First of all, rename both outer and inner project directory name from old_project_name to new_project_name
So if the project directory looks like this :
old_project_name // outer project directory old name
old_project_name// inner project directory old name
--__init__.py
--asgi.py
--settings.py
--urls.py
--wsgi.py
app_name // any app u created in the project
db.sqlite3
manage.py
then change to this :
new_project_name // outer project directory new name
new_project_name// inner project directory new name
--__init__.py
--asgi.py
--settings.py
--urls.py
--wsgi.py
app_name // any app u created in the project
db.sqlite3
manage.py
In 2021 with Django version 3.2.3, there are in total 9 places (including comments and codes both) in 5 files where the name of the project appears, which are :
In new_project_name/asgi.py file (comment) :
ASGI config for old_project_name project.
In new_project_name/asgi.py file (code) :
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'old_project_name.settings')
In manage.py file (code) :
os.environ.setdefault('DJANGO_SETTINGS_MODULE', old_project_name.settings')
In new_project_name/settings.py file (comment) :
Django settings for old_project_name project.
In new_project_name/settings.py file (code) :
ROOT_URLCONF = 'old_project_name.urls'
In new_project_name/settings.py (code) :
WSGI_APPLICATION = 'old_project_name.wsgi.application'
In new_project_name/urls.py file (comment) :
old_project_name URL Configuration
In new_project_name/wsgi.py file (comment) :
WSGI config for old_project_name project.
In new_project_name/wsgi.py file (code) :
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'old_project_name.settings')
Note : To change the old_project_name to new_project_name in the files you can use your IDE 's/ text editor's find & replace function to avoid any errors.
Tip : If you haven't done much work in the project then its better to create a new Django project and then just copy and paste the code which don't need any changes rather than changing project name.
I think the best solution here is to simply open your settings.py, urls.py, views.py and any other file that might rely on your project's name and then use the find&replace function in your text editor.
Or, if you haven't done much work yet, start a new project with django-admin.py and copy/paste.
As a beginner with Python and Django, the below simple steps worked for me.
Update both outer and inner folder names in your project (directly from windows explorer or from any editor like visual studio)
Search and replace your old project name with new one in below project files
a. manage.py
b. settings.py
c. wsgi.py
d.asgi.py
e. urls.py
Restart server and confirm if everything works fine again
Actually what you have to do is this:
Open your project in any code editor like Sublime or VSCode
Search for your current project name
In the replace box enter the new project folder name that you want.
Now the code editor will automatically search in the whole project folder and will replace the current project name with the new name.
Now just rename the main app name which is in your project folder
You can now rename your project folder name
Thats it. Hope that helps :)
Suppose your project name is old_project_name and you want to change it to new_project_name. Also you have created an app called my_app within old_project_name. Your directory structure will be something like -
old_project_name
--old_project_name
--__init__.py
--settings.py
--urls.py
--wsgi.py
my_app
--Files and folders under my_app
db.sqlite3
manage.py
Rename both inner and outer old_project_name directory name to new_project_name. After changing your directory structure will be as something like -
new_project_name
--new_project_name
--__init__.py
--settings.py
--urls.py
--wsgi.py
my_app
--Files and folders under my_app
db.sqlite3
manage.py
Change reference to old_project_name in your project files to new_project_name. Mostly you will need to change the reference in settings.py, wsgi.py and manage.py
After these changes run local server and check if your routes are working fine.
Change git repository name. This is optional, but it is advisable as it will be easy to track your projects. If you have added your project to bitbucket or github, then login into bitbucket or github and change the repository name to new_project_name. Suppose your old repository url is https://<yourusername>#bitbucket.org/<yourusername>/old_project_name.git
After renaming repository, your project git url will be changed to something like https://<yourusername>#bitbucket.org/<yourusername>/new_project_name.git>
Run in terminal
git remote -v
it will list your current remote repository url
origin https://<yourusername>#bitbucket.org/<yourusername>/old_project_name.git(fetch)
origin https://<yourusername>#bitbucket.org/<yourusername>/old_project_name.git(push)
Run following command in terminal. This will change your current remote repository url
git remote set-url origin https://<yourusername>#bitbucket.org/<yourusername>/new_project_name.git
Run in terminal
git remote -v
It will now list something like
origin https://<yourusername>#bitbucket.org/<yourusername>/new_project_name.git(fetch)
origin https://<yourusername>#bitbucket.org/<yourusername>/new_project_name.git(push)
Now you can push your new updates to your remote repository.
Update virtual environment. This is optional,but it will help to identify virtual environ mapping to project. I use virtualenvwrapper. If you are using a different one, you will have to update the commands as per your virtual environment.
Run following command in terminal. This will create a copy of old_project_name environment setting with name new_project_name.
cpvirtualenv old_project_name new_project_name
Remove old environment. This step is optional as well.
Run following command in terminal
rmvirtualenv old_project_name

django apache problem , how can i run django project with apache?

https://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/
Where would i add this?
path = '/path/to/mysite'
if path not in sys.path:
sys.path.append(path)
You should create a file django.wsgi and put that line there. In m case, django.wsgi contains,
import os
import sys
sys.path.append('H:/Projectys/mysite')
sys.path.append('H:/Projects/mysite/mysite')
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
I have added sys.path such that because my project tree is
+H
++Projects
+++mysite
++++mysite
+++++apache
++++++django.wsgi
+++++mysite
++++++setting.py
++++++__init__.py
++++++urls.py
++++++view.py
+++++media
You should reference the location of django.wsgi in your httpd.conf (apache conf)
FWIW, you should also read the official mod_wsgi documentation as well.
http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
Technically it doesn't matter where in the file you place the lines adding extra directories to sys.path if they are only referring to where your Django site directory it. This is because they only need to be set up by the time the first web request occurs. That is, the first time the application object is called.
So, if you stuck them as the very last thing in the file it would actually still work. In general though, it looks more logical to stick them in before you actually import Django modules. By doing that you ensure that if Django were ever changed to do loading up front rather than lazy loading on first request that it will still work.
Obviously they at least have to be after the import of 'sys' though.
Just after this code, it is written :
just below the import sys line to
place your project on the path.
Remember to replace 'mysite.settings'
with your correct settings file, and
'/path/to/mysite' with your own
project's location.

Using a settings file other than settings.py in Django

I want to use a different settings file in django -- specifically settings_prod -- yet whenever I try to do a syncdb with --settings=settings_prod, it complains:
python2.6 manage.py syncdb --settings=settings_prod
Error: Can't find the file 'settings.py' in the directory containing 'manage.py'. It appears you've customized things.
You'll have to run django-admin.py, passing it your settings module.
(If the file settings.py does indeed exist, it's causing an ImportError somehow.)
I've also tried setting the environment variable DJANGO_SETTINGS_MODULE=settings_prod to no end.
Edit: I have also set the environment variable in my wsgi file, also to no end:
import os
import sys
from django.core.handlers.wsgi import WSGIHandler
os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings_prod'
application = WSGIHandler()
Suggestions?
Try creating a settings module.
Make a settings folder in the same directory as manage.py.
Put your different settings files in that folder (e.g. base.py and prod.py).
Make __init__.py and import whatever settings you want to use as your default. For example, your __init__.py file might look like this:
from base import *
Run your project and override the settings:
$ python2.6 manage.py syncdb --settings=settings.prod
I do know that no matter what you do with manage.py, you're going to get that error because manage.py does a relative import of settings:
try:
import settings # Assumed to be in the same directory.
http://docs.djangoproject.com/en/dev/ref/django-admin/#django-admin-option---settings
Note that this option is unnecessary
in manage.py, because it uses
settings.py from the current project
by default.
You should try django-admin.py syncdb --settings=mysettings instead
this works for me:
DJANGO_SETTINGS_MODULE=config.settings.abc python manage.py migrate
this will help you:
create a another file "setting_prod.py" with your original settings.py file.
write down your setting which you need to run, in setting_prod.py file.
Then import setting_prod.py file in your settings.py file.
for ex.
settings.py:
VARIABLE = 1
import setting_prod
setting_prod.py
VARIABLE = 2
After importing setting_prod.py file in settings.py file, VARIABLE will set to new value to "2" from "1".
We can use this method to set different settings file, for example, I use different settings file for my unit test (settings_unit_test.py). Also I do have other settings file for different infrastructure environment settings_dev.py, settings_test.py and settings_prod.py.
In windows environment(same can done in linux as well)
set DJANGO_SETTINGS_MODULE=settings_unit_test
set PYTHONPATH=<path_of_your_directory_where_this_file_'settings_unit_test.py'_is_kept>