Serve static files when using the Django WSGI app - django

I am using the python-reload package. The readme gives this code to use it with django:
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hello.settings")
from django.core.management import execute_from_command_line
if 'livereload' in sys.argv:
from django.core.wsgi import get_wsgi_application
from livereload import Server
application = get_wsgi_application()
server = Server(application)
# Add your watch
# server.watch('path/to/file', 'your command')
server.serve()
else:
execute_from_command_line(sys.argv)
However Django doesn't serve staticfiles anymore. The runserver command still works, so I guess it's related to the wsgi app. How can I made django serve static files when using WSGI? Is it posible?

Related

Django os.getenv('SECRET_KEY') throwing "The SECRET_KEY setting must not be empty."

I'm setting up Django using os.getenv to prepare it for deploying using Docker but it seems it is not reading the .env file. Any idea why is not reading it?
Here is the setup:
.env
SECRET_KEY=foo
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
settings.py abstraction
import os
from pathlib import Path
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = os.getenv('SECRET_KEY')
DEBUG = os.getenv('DEBUG')
ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS')
You can use python-decouple to get the environment variable stored in the root of your project in a .env file.
from decouple import config
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
EMAIL_HOST = config('EMAIL_HOST', default='localhost')
EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
Note: for changes to apply you need to restart the server.
I'm using python-dotenv in order to implement dotenv functionality. If you want Django to find your .env file, you need to modify manage.py and wsgi.py files.
# manage.py
import os
import sys
import dotenv
def main():
"""Run administrative tasks."""
# dotenv settings
dotenv.load_dotenv(
os.path.join(os.path.dirname(__file__), '.env')
)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
if os.getenv('DJANGO_SETTINGS_MODULE'):
os.environ['DJANGO_SETTINGS_MODULE'] = os.getenv('DJANGO_SETTINGS_MODULE')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
# wsgi.py
import os
import dotenv
from django.core.wsgi import get_wsgi_application
# dotenv settings
dotenv.load_dotenv(
os.path.join(os.path.dirname(os.path.dirname(__file__)), '.env')
)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
if os.getenv('DJANGO_SETTINGS_MODULE'):
os.environ['DJANGO_SETTINGS_MODULE'] = os.getenv('DJANGO_SETTINGS_MODULE')
application = get_wsgi_application()
When deploying via docker-compose, you can specify in the docker-compose file.bml in the container settings [web]:
web:
...
env_file:
- ./.env
It worked for me without using additional packages. In my case , the file .env is located in the directory where docker-compose.yml is located
To get environment variables from docker or from the AWS Elastic Beanstalk i use
os.environ.get('SECRET_KEY'), this is generally more reliable than os.environ['SECRET_KEY']

setting up Django app to work on google app engine GAE (app.yaml & main.py)

I have a working Django app that I was able to get functioning on Heroku. The structure is project named 'untitled' and an app named 'web' such that the structure is:
project_root
static
templates
untitled
--->init.py
--->settings.py
--->urls.py
--->wsgi.py
web
--->init.py
--->admin.py
--->apps.py
--->models.py
--->tests.py
--->urls.py
--->views.py
This is a fairly basic app that I can get working outside of GAE (local and on Heroku), however, I'm getting stuck on the app.yaml and main.py requirements for GAE.
My app.yaml is:
application: seismic-interpretation-institute-py27
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: main.app
libraries:
- name: django
version: "latest"
and my main.py (generated from PyCharm) is
import os,sys
import django.core.handlers.wsgi
import django.core.signals
import django.db
import django.dispatch.dispatcher
# Google App Engine imports.
from google.appengine.ext.webapp import util
# Force Django to reload its settings.
from django.conf import settings
settings._target = None
os.environ['DJANGO_SETTINGS_MODULE'] = 'untitled.settings'
# Unregister the rollback event handler.
django.dispatch.dispatcher.disconnect(
django.db._rollback_on_exception,
django.core.signals.got_request_exception)
def main():
# Create a Django application for WSGI.
application = django.core.handlers.wsgi.WSGIHandler()
# Run the WSGI CGI handler with that application.
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
Finally, the output that is reported when running locally is
It seems that the error,
ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.
is causing my problems. I am not exactly sure how to fix it.
try replace
from django.conf import settings
settings._target = None
os.environ['DJANGO_SETTINGS_MODULE'] = 'untitled.settings'
to
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled.settings")
from django.conf import settings
settings._target = None

Django Gunicorn no module named error

My project directory structure looks like following:
My wsgi file:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
application = get_wsgi_application()
and my manage.py file:
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)
in my settings .py I have:
WSGI_APPLICATION = 'config.wsgi.application'
I added my project path to python with following:
export PYTHONPATH=/home/ec2-user/amm_inovision_backend:$PYTHONPATH
and I am trying to run gunicorn command where my manage.py file is as: gunicorn amm_inovision_backend.config.wsgi:application
But it throws me error no module named amm_inovision_backend.config.wsgi
If I run instead gunicorn config.wsgi:application it throws no module named amm_inovision_backend.config.settings
What am I doing wrong?
Note: in the screenshot it is amm_ino_backend but actually it is amm_inovision_backend in the production
when you want to use gunicorn you must run gunicorn installed on your virtual environment.
so you don't need to export any python path, you only need to find path to gunicorn on your virtual-env where Django is installed, or you can add path to virtual environment not to project files.
also you need first to edit your wsgi.py
you have to replace this
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") with
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
your command must be something like that:
/path/to/.virtual-envs/your-env/bin/gunicorn config.wsgi:application
Use:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = get_wsgi_application()
note the "CONFIG.SETTINGS"

Django Shell in Eclipse not starting

I am getting this error message when I try to run the shell from Eclipse Neon while I can successfully run the Django shell from command window. I am using Python 3.4 and Django 1.10. Any idea where the problem is?
WSGI file:
'''
WSGI config for MyProject project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/
'''
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MyProject.settings")
application = get_wsgi_application()
I beleive This is a known bug in Eclipse Pydev.
https://www.brainwy.com/tracker/PyDev
Fixed for 5.6
Git: 2c8cd03 2017-03-12 Fabio Zadrozny #PyDev-752: Django version not
detected if > 1.10
And a fix has been posted for it.
You could try start a python shell as normal, then:
import sys; print('%s %s' % (sys.executable or sys.platform, sys.version))
import os; os.environ['DJANGO_SETTINGS_MODULE'] = '<Project Name>.settings'; import django
sys.path.append(os.path.expanduser('<path to your project>'))
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Replace 'Project Name' with your project name and 'path to your project' with your path
alternatively, use a pre 1.10 version of Django i.e 1.7

Django cannot find settings?

Everything was working before but all of a sudden
python manage.py runserver
throws an error
line 41, in import_module
return sys.modules[name]
KeyError: 'settings.base'
my PYTHONPATH is pointing to the root folder of my django project.
my manage.py is:
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.base")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
I have a settings folder in which I have the base.py file. That file pulls in environment specific settings.
if os.getenv("PLATFORM") == "Heroku-Master":
from .heroku_master import *
elif os.getenv("PLATFORM") == "Heroku-Dev":
from .heroku_dev import *
elif os.getenv("PLATFORM") == "Heroku-Prod":
from .heroku_prod import *
else:
from .local import *
except Exception as e:
pass
What could be the issue ?
Is your file named settings.py?
Suppose that your project root is on /home/username/workspace/ProjectDjango and you have the following structure:
workspace
ProjectDjango
manage.py
YourAppFolder
settings.py
Your config should be:
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "YourAppFolder.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)