I used python manage.py runserver to start the django server locally. I noticed the change of HTML code is not reflected if I don't re-start the server. Is it normal? Is it possible to see the change without restarting the server?
Update:
I saw the I am in the production env, so the Debug is False. I am wondering how can I change to Development mode?
It is always recommended to create a local settings so you can work in a "development environment", so, you can have a settings.py where you set all the configuration for your production server, always with DEBUG=False, never set DEBUG=True in production.
And also, you can additionally create a local_settings.py where you change only those variables that you need to change for your development environment, like the DEBUG value, so, in your local_settings.py you can have only this:
# local_settings.py
DEBUG=True
And in your settings.py add this at the end:
# settings.py
try:
from local_settings import *
except ImportError:
pass
This will override the variables you set in the local_settings when you run the development server.
Make sure you don't push this file to your server (if you're using git add it to your .gitignore file)
Related
I deployed my Django-project via Apache2 on a server.
The problem I have is that I have two setting-modules: settings.py which are my local development settings and settingsprod.py which are my productive settings.
I found the following line in the WSGI.py:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proj.settings")
Is this module only called when using WSGI? And if yes is this a good place to use my production settings like so?
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proj.settingsprod")
For local development I use the development server like so:
python3 manage.py runserver
Does this still defaults to settings.py then?
Yes, your setup works as expected. Though if you use extra tools like celery, you might need to also specify the settingsprod for those setups aswell.
The way I handle such a situation is exactly the other way around: I use settings.py for my production settings and have an additional settings_development.py that I use for all development tasks. This way I don't have to remember setting the production settings in all production relevant files, but instead simply use the development settings for development like so:
python3 manage.py runserver --settings=proj.settings_development
If you often use manage.py commands and want to save some time typing, you can make a copy of your manage.py e.g. as manage_dev.py and change the settings module line like so:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proj.settings_development")
and then call your manage functions with:
python3 manage_dev.py runserver
On my production server, I've set environment variables both inside and outside my virtualenv (only because I don't understand this issue going on) including a variable HELLO_WORLD_PROD which I've set to '1'. in the python interpreter, both inside and out my venv, os.environ.get('HELLO_WORLD_PROD') == '1' returns True. In my settings folder, I have:
import os
if os.environ.get('HELLO_WORLD_PROD') == '1':
from hello_world.settings.prod import * # noqa
else:
from hello_world.settings.dev import * # noqa
Both prod.py and dev.py inherit from base.py, and in base DEBUG = False, and only in dev.py does DEBUG = True.
However, when I trigger an error through the browser, I'm seeing the debug page.
I'm using nginx and gunicorn. Why is my application importing the wrong settings file?
You can see my gunicorn conf here
Thanks in advance for your patience!
I was using sudo service gunicorn start to run gunicorn. The problem is service strips all environment variables but TERM, PATH and LANG. To fix it, in my exec line in my gunicorn.conf I added the environment variables there using the --env flag, like exec env/bin/gunicorn --env HELLO_WORLD_PROD=1 --env DB_PASSWORD=secret etc.
I have a Django application deployed to cloudControl. Configuration is standard and the push/deploy happens without (apparent) errors.
But the collectstatic step is not being executed: it fails silently (I see no -----> Collecting static files message). After the deploy, the static folder for the application is empty, so you get 500 Server Errors continually.
I can solve it changing the Procfile, but it is not consistent either:
web: python manage.py collectstatic --noinput; gunicorn app.wsgi:application --config gunicorn_cnf.py --bind 0.0.0.0:${PORT:-5000}`
collectstatic works as it should locally, and if I run cctrlapp app/deployment run "python manage.py collectstatic --noinput" no errors are shown either:
669 static files copied to '/srv/www/staticfiles/static', 669 post-processed.
But /srv/www/staticfiles/static is empty.
How can I know why collectstatic is not being executed in the push phase?
I've been able to debug the problem, using a custom python buildpack, so here is the answer for further reference.
The problem was in the settings.py file. The first thing I do in this file is to check if we are in a cloudControl environment or in a local environment. I do it looking for the CRED_FILE environment variable (not so different of what is suggested): if no variable is found, I load a local JSON file that mimics that credentials variable for development:
try:
cred_file = os.environ['CRED_FILE']
DEBUG = False
except KeyError:
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True
Once I know the environment, I can have different INSTALLED_APPS (requirements.txt files are slightly different in production and development, too) or change some settings.
Now the bad news: in the push phase there is no CRED_FILE available.
So I was trying to load apps that were not installed (because they were only in the development requirements file, like coverage or django-debug-toolbar) or use credentials that were not set (creds.json is, of course, not uploaded to the repository: only a TXT with dummy values is uploaded as a reference). That's why collectstatic was failing silently in the push phase.
Here is my solution (it will work as long as you have a dummy credentials file in your repo):
try:
cred_file = os.environ['CRED_FILE']
DEBUG = False
except KeyError:
if os.path.exists(os.path.join(BASE_DIR, 'creds.json')):
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True
else:
cred_file = os.path.join(BASE_DIR, 'creds.json.txt')
DEBUG = False
Credentials are not used by collectstatic, so you can have anything in the creds.json.txt file. Not very clean, but it works as expected now.
EDIT
As pointed by #pst in a comment there is an environment variable to know if the buildpack is running, so we could use that one too to load the desired credentials and set DEBUG.
if 'CRED_FILE' in os.environ:
cred_file = os.environ['CRED_FILE']
DEBUG = False
elif 'BUILDPACK_RUNNING' in os.environ:
cred_file = os.path.join(BASE_DIR, 'creds.json.txt')
DEBUG = False
else:
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True
I'm following the approach in Two Scoops of Django: Best Practices for Django 1.6 regarding multiple settings files. I'm using Django 1.7 and virtualenvwrapper.
My setup is as follows:
project/
app1/
app2/
project/
__init__.py
settings/
__init__.py
base.py
local.py
production.py
manage.py
I'm a bit confused as to how Django knows which settings file to use. I do not want to specify the settings file every time I run manage.py. I would rather like to set the DJANG_SETTINGS_MODULE environmental variable as explained in omouse anser here:
What confuses me is in the wsgi.py file there is a line:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings.production")
Is this file only used in the production server? What happens if I already have a DJANGO_SETTINGS_MODULE environmental variable defined on the server?
When running it locally, I understand I need to set the DJANGO_SETTINGS_MODULE env variable every time I open the console. I've read here that I can define a postactivate hook in virtualenvwrapper. This hook will then create the environmental variables that I require everytime I activate the environment.
Is this the recommended way of ensuring the correct DJANGO_SETTINGS_MODULE env variable is loaded on my local machine? Would I also need to setup a similar file on my hosting server? I'm planning on using PythonAnywhere for hosting.
Lastly, if I run a staging server, how would I tell Django to load the staging settings file? The staging server is the practically the same as the production server, so I guess need a different wsgi.py file for the staging server, but that seems like a anti-pattern.
os.environ.setdefault only sets the value if it is not set. When you run in production, export the environment variable DJANGO_SETTINGS_MODULE and set it to your production/staging settings file, and you don't have to set anything when running in development (if you set it by default to your development settings). This is the DRY-est method.
The method with a local_settings.py (which is most of the times kept out of the repo!) is not best practice and should be avoided.
I have a problem setting my Django application for deployment on openshift and testing locally.
Here is my structure
root_folder/
my_project/
anoter_app/
urls.py
views.py
my_project/
settings.py
urls.py
views.py
manage.py
application.py (to tell openshift where my settings file is: my_project.myproject.settings)
So for it to work on the deployment server, in the settings, the ROOT_URL_CONF is:
myproject.myproject.urls
and in my url file, the view must be reached as myproject.myproject.views
But when I want to work locally, I have to change the ROOL_URL_CONF as myproject.urls
and the views are reached with myproject.views
How do I make it work both locally and on the deployment server with the same settings?
Thank you
Create a new file named local_settings.py, at the bottom of your settings.py add:
try:
import local_settings
except:
print 'CAUTION -- NOT USING LOCAL SETTINGS!'
Put any settings you need to override on your local environment in your local_settings.py file.
I resolved it, the problem was that the folder and the app had the same name.
I renamed the app and now i dont'have to do myproject.myproject