Common practice for setting environment variables in Django? - django

I'm very new to the Django framework. I am writing an app, and I would like to set a number of environment variables before the server is run. Is there a standardized approach to doing this (i.e. a setup script that is run before the server startup is completed)?

It depends upon webserver you want to use. For example apache with mod_wsgi you can add your variables in the os.environ. Refer WSGI IntegrationWithDjango
However, in general updating os.environ in setttings.py would also work.

Related

Django - distinguish development server (manage.py runserver) from the regular one (eg. Apache)

I need a way to distinguish development server in Django (run eg. by ./manage.py runserver 0.0.0.0:8000) from the one being run on Apache. In case of Apache I use WSGI daemon mode, but I would like to find some more reliable solution for detecting execution on Django's development server.
What I currently use is similar to:
wsgi_wrapper = request.META.get('wsgi.file_wrapper')
wsgi_wrapper_path = wsgi_wrapper.__module__ if wsgi_wrapper else None
which seemingly gives wsgi_wrapper_path storing:
"wsgiref.util" string when run on Django's built-in development server,
None when run on Apache / WSGI in daemon mode,
The problem here is I am not sure if I can rely on that check (eg. if the production/staging/development server or my localhost configuration changes). I was not able to find any documentation regarding that.
I need that check primarily because of one issue with Django's development server: it sets request's CONTENT_TYPE (request.META['CONTENT_TYPE']) to "text/plain" even if the HTTP request itself had no content type set (eg. it was a GET request).
Any ideas regarding Django's development server detection (or solving issue with incorrect request content type on it) will be appreciated. Thanks.
Ps. I am basically asking this question: How can I tell whether my Django application is running on development server or not? for Django 1.4, trying to determine the solution that will be reliable enough in case configuration changes.
As a principle - when using a Production and Dev servers, they should have different configs - it is most common that they will use different databases, different mail settings, etc.
So the best place to tell the kind of the server is the configuration. I can point to two most-used approaches:
Config file
then in settings.py just add:
server = config.get("SERVER_TYPE", "DEV")
and have SERVER_TYPE only in the config file on PRODUCTION
Environment
Set SERVER_TYPE as environment variable when running the web server. I.e. for Supervisord, running the webserver:
environment=SERVER_TYPE=PROD
or for Apache:
SetEnv SERVER_TYPE PROD
This way you will be sure that as long as you don't mix the config files, you will always get the real server type, no matter how you start the server.
At least that why config files are used for.

Django views that are inaccessible publicly but accessibly internally?

I have a few views I want to expose to apps internal to the server cluster. How can I do this securely?
The apps that want to access these restricted views are also using python, so if I can arguably bypass the HTTP tunneling and call directly to them, that's even better. I think these would be better suited as commands if that's the case, but how can another process invoke a Django environment's commands?
Once you load the project's settings you can act as the project itself.
It sounds like you basically want to extract some data from your Django site and use it elsewhere. Perhaps a couple of management commands that periodically output their data in some directory which you can then read from the other python apps? Depends on your data needs whether that's an option.
I'm doing this suggestion as those other apps seem to be on the same server (how could you otherwise run your site's python code from those apps?).

Set up an existing Django app on another server

This must, must, must be a duplicate but I can't find the answer either here or on Google.
I have an existing Django app and I want to deploy it on another server.
What are the steps I need to go through to get it running elsewhere, in words of one syllable?
At a minimum, presumably:
create a project on the new server
copy over all my app's files into that project
edit localsettings.py or equivalent with local database settings etc
run python manage.py syncdb to create my database
load fixtures
run tests
Is that it? Are there any unofficial or official instructions for copying an app elsewhere?
Thanks.
The most basic, easy way to do it is:
Set up the server environment so that it matches the current environment as closely as possible. The most important thing is that you're using the same version of Django (obviously). You can run a different database, but it makes porting from the old server to the new server a little more involved. Otherwise, you will just have to adjust your settings to match the new server, if they can't be duplicated (ie, user names, etc).
Copy over your code
Dump your old database structure and data into the new database
Running startproject isn't strictly necessary. Your web server just needs to be configured correctly, to run django with the appropriate settings.py file -- and Django takes it from there.

Using Django's built in web server in a production environment

I'm going to setup a simple Django app running in a production environment on a Linux box. The app will have very little traffic - less that 100 page loads per day. Is it okay to use the builtin Django webserver for this or should I install Apache and mod_wsgi? If so, what are the reasons for this? Security perhaps?
UPDATE
OK it is clear I shouldn't be using the builtin server. Some of the alternatives to Apache look interesting. Is there one that is more popular/more frequently used with Django perhaps?
Is it okay to use the builtin Django webserver for this
No.
Should I install Apache and mod_wsgi?
Yes.
If so, what are the reasons for this? Security perhaps?
Partly.
More importantly, the little toy Django server is single-threaded and any hangup in your code hangs the server. This means that when two users click almost at the same time, user one's query must go all the way through Django before user two's query can even starts.
And this will have to include the insanely slow download speed to the desktop.
Apache (like all the alternatives, lighttpd or nginx) is multi-threaded. The slowest part of the transaction is the download from Apache to the desktop. You don't want Python code (and Django) handling this in a single-threaded manner. Even for just a few users.
Also, you don't what Django serving static media (i.e., CSS and JS library files.)
A single slow spot in your application won't effect the overall system throughput if Apache and mod_wsgi are in place. One request 's output page can be slowly downloading to a PC desktop in parallel with another user's output.
DO NOT USE THIS (the builtin Django webserver) SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests.
http://docs.djangoproject.com/en/dev/ref/django-admin/#runserver-port-or-address-port
But you don't have use Apache if you don't want to. You could directly use Spawning, Gunicorn etc.
Cherokee is also easy to setup.
Use nginx + gunicorn.
Nginx: five lines of configuration. Gunicorn: two lines of configuration. That's easy and efficient. For better control you can spawn the gunicorn process using supervisord.
Both gunicorn and supervisord are available to install with pip, and nginx is available in almost any distribution in the default package pool.
The built in Django server was not built for production. There are many reasons why, mainly security and efficiency.
The recommended way is to use mod_wsgi which is covered in the docs here

django beginner book... uses mod_wsgi

I notice that the official recommended book "The Definitive Guide to Django" was written based on mod_python, for both editions.
However, I think most beginners would follow what most people use: mod_wsgi.
I followed their first tutorials, that is, display current time
I have the mod_wsgi and everything setup correctly. But I am still getting the default page regardless how I access to http://domain/time/
Is there any book that is written for mod_wsgi, or did t setup the environment incorrectly?
I know I can begin without using apache, but it would be a headache in the future to deploy apache again...
EDIT
I added the wsgi script and inclued that in the views.py. It seems to work. Is it the right way???
So what is the purpose of having a separate wsgi script anyway?
I know the official guide said that create a folder name such as /apache/ and create django.wsgi...
You don't need a full rewrite of the Django book for mod_wsgi. The ony thing that is different is the apache.conf and the script inside your cgi-bin directory (both aren't directly related to Django, so all the Django parts will apply for both).
But you might probably find it useful to read the general usage/configuration instructions for mod_wsgi, and probably the special notes about django too. If you have some troubles (e.g. some kind of error message in your apache.log) then you might look at the ConfigurationIssues page too.
So what is the purpose of having a separate wsgi script anyway?
Nearly all Python web applications are based on the WSGI specification, which allows your application to be used with CGI, FastCGI, mod_python, mod_wsgi, etc. So, you might have more than one of those scripts - one for each technology for example.
Another thing is, that you can also control a lot of configuration settings inside this script (e.g. forking of additional python processes for increased performance, path to additional python modules or different versions of existing modules) which are normally set by the server administrator (and not the application developer). Thats probably also the main reason why such scripts aren't included directly in the applications.
And the third thing is, that you might have several such wsgi scripts which are deploying the same application with different settings. For example, you might have your application deployed several times for different users, or with different database settings (e.g. production and testing).