Insert http request header for debugging - django

I'm testing a Django application on my local environment using python manage.py runserver 0.0.0.0:8000
When the app is running in production, the client has a web proxy that validates you against AD and inserts a http header. But for debugging, I can't run though that proxy. In order to test, I've been using the Firefox plugin "Modify Headers" to insert a version of this header, but now I've got a bug that requires me to insert that header in IE. I'd rather not modify the source because there is a risk that it might end up getting checked in, so I'm looking for something I can either put in the app settings.py or a script or something I can run between the testing server and the client (but which doesn't require anything to be installed because everything is locked down here).

Let's say this is your settings.py:
VARIABLE_THAT_YOU_NEED = "VALUE A"
In the end of your settings file you just have to add this line:
if 'test' in sys.argv:
try:
from test_settings import *
except ImportError:
pass
Now you create a new file named "test_settings.py", inside of this file you override ONLY what you need for testing, in your case:
VARIABLE_THAT_YOU_NEED = "VALUE B"
So, when you run your server, you will have your variable normally and when run tests this variable will be replaced!

Related

How can I detect that my code is running through the Django shell?

In some cases, we do manual cleanup for our app via the Django shell (python manage.py shell). Of course this should be done with care but in this particular internal app it's just the most effective way to do the work.
When running in the Django shell, I'd like to disable some behavior that otherwise would be triggered.
How do I detect that my code is running through the shell?
I'm imagining something like:
if not django.SHELL:
# Don't notify chat when running from the shell
notifications.send(dev_user, ...)
Use a different settings file and include a flag in that that you can determine, then you can use manage.py's --setting flag to use that settings file
Add a setting in a new settings file to override and include one in your normal settings file that defaults to true
SEND_NOTIFICATIONS = False
In code
from django.conf import settings
if not settings.SEND_NOTIFICATIONS:
Call the shell with the correct settings file
python manage.py shell --settings=settings.my_override

Created a brand new Django Project, attempting to run the server generates an Improperly Configured Error

I have been working on a Django Project for a bit, until I took a break. One month later I dug back in to the project and went to run the server. I received an error:
django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
I figured I must have tweaked something by accident. So I created a brand new Django Project (using a virtual environment), and just went to test the server. I received the same error. I tried the python manage.py shell solution listed in another answers but to no avail.
If it helps I'm on Linux with Django version 2.1.5 and Python 3.6.
Edit:
If anyone encounters something similar I found using python3 manage.py runserver works in place of using django-admin. Per Greg's answer below, I did begin to receive a new error ModuleNotFoundError: No Module named "mysite" exists. I will continue to search for an answer on that front.
Going off of the comments here.
If "env | grep DJANGO_SETTINGS_MODULE" returns empty, it means you have to set an environment variable stating where your settings.py file is located.
This can be done by doing the following:
export DJANGO_SETTINGS_MODULE=mysite.settings
Be sure to replace "mysite" with the name of your app!

Django and loading config file before server starts

My django app is communicating with external server and before running django server i would like load some config file. Variables from this file are going to be used by some module while app is running
Problem is that config file can be located in many places.
My dream would be to run manage.py --cfg "/path/to/cfg/file.cfg" or
manage.py runserver --cfg "/path/to/cfg/file.cfg"
and some variables (like globals?) are going to be loaded and they are going to be avaible for django modules to be used. After django server shutdown those variables can dissapear
Is there some nice way to accomplish this?
There seem to be two parts to your problem:
How do I support changing which set of variables (as defined in a config file) are used for a given run
How can I load these variables such that they are visible to all the modules of my application.
The standard mechanism for doing the 2nd is to put stuff in settings.py.
If you do FOO="bar" in settings.py, in your module you can do:
from django.conf import settings
if settings.FOO == "bar":
# Do something
As far as how you can support multiple configurations, the first thing I could come up with is to rename your real settings.py to be real_settings.py and then create a series of config1_settings.py, config2_settings.py, config3_settings.py ... which look like:
from real_settings.py import *
from path_to_configX.py import *
where configX.py has all the values for whatever variables you want for configuration X.
You would then start django's built in server via:
manage.py runserver --settings=configX_settings.py
Note that doing this for a production server (where you can't as easily just pass something on the command line to kick it off) may be a bit trickier, but you're going to need to provide more use case details for that.

Configuring postgresql database for local development in Django while using Heroku

I know there are a lot of questions floating around there relating to similar issues, but I think I have a specific flavor which hasn't been addressed yet. I'm attempting to create my local postgresql database so that I can do local development in addition to pushing to Heroku.
I have found basic answers on how to do this, for example (which I think is a wee bit outdated):
'#DATABASES = {'default': dj_database_url.config(default='postgres://fooname:barpass#localhost/dbname')}'
This solves the "ENGINE" is not configured error. However, when I run 'python manage.py syncdb' I get the following error:
'OperationalError: FATAL: password authentication failed for user "foo"
FATAL: password authentication failed for user "foo"'
This happens for all conceivable combinations of username/pass. So my ubuntu username/pass, my heroku username/pass, etc. Also this happens if I just try to take out the Heroku component and build it locally as if I was using postgresql while following the tutorial. Since I don't have a database yet, what the heck do those username/pass values refer to? Is the problem exactly that, that I need to create a database first? If so how?
As a side note I know I could get the db from heroku using the process outlined here: Should I have my Postgres directory right next to my project folder? If so, how?
But assuming I were to do so, where would the new db live, how would django know how to access it, and would I have the same user/pass problems?
Thanks a bunch.
Assuming you have postgres installed, connect via pgadmin or psql and create a new user. Then create a new database and with your new user as the owner. Make sure you can connect via psql with the new user into to the database. you will then need to set up an env variable in your postactivate file in your virtualenv's bin folder and save it. Here is what I have for the database:
export DATABASE_URL='postgres://{{username}}:{{password}}#localhost:5432/{{database}}'
Just a note: adding this value to your postactivate doesn't do anything. The file is not run upon saving. You will either need to run this at the $ prompt, or simply deactivate and active your virtualenv.
Your settings.py should read from this env var:
DATABASES = {'default': dj_database_url.config()}
You will then configure Heroku with their CLI tool to use your production database when deployed. Something like:
heroku config:set DATABASE_URL={{production value here}}
(if you don't have Heroku's CLI tool installed, you need to do it)
If you need to figure how exactly what that value you need for your production database, you can get it by logging into heroku's postgresql subdomain (at the time this is being written, it's https://postgres.heroku.com/) and selecting the db from the list and looking at the "Connection Settings : URL" value.
This way your same settings.py value will work for both local and production and you keep your usernames/passwords out of version control. They are just env config values.

Read/Write permission for a program run with subprocess?

I've got a Django app, which calls a program using subprocess.call(). This program creates a couple of files, which I then use back in my app. The problem is the program doesn't seem to have permission to create files. I also tried calls like subprocess.call(['mkdir','/tmp/myapp']) but the directory was not created. What do I need to do?
This is just with my dev server at the moment, which I invoke with
sudo python manage.py runserver 0.0.0.0:8080
I can run the command from the terminal manually fine.
I can also use subprocess to touch the files, which it does fine, but when it runs the program that accesses the files itself, that program throws an error because it cannot.
The /tmp/myapp directory needs to be created first. If your view function in Django doesn't show you an error it means that you are not catching it properly.
Try something like this:
response = HttpResponse()
calltxt = subprocess.call(['mkdir','/tmp/myapp'])
response.content = calltxt
return response
Append the function to your urls.py and load it in the browser.
0 means the command executed successfully, 1 means error (this is similar to the $! variable in Bash).
I think it's not the case but if your Django app is deployed in the Web Server the user that creates files and executes commands out of the Python environment is the one that owns the web server daemon. For instance www-data in Apache.
Thus, it is needed to change permissions for this user also in order to write and execute commands out of their normal scope.