Django is a web development framework for Python in the same way rails is a framework for Ruby. It is used by a number of major web sites, including Google (i.e., for the Google Application Engine), and can make developing rich web applications much easier.
Django is not an application on its own, however. You will need proficiency in Python programming in order to write an application using Django. If you are not already familiar with Python, a good starting point is Dive Into Python.
|Note:||As of Feb 2012, DH is currently running Django v1.2.3|
- 1 Setting up Django
- 2 Migrating existing sites from FastCGI to Passenger
- 3 Custom Python and Django install
- 4 Troubleshooting
- 5 Sending Email
- 6 Performance Improvements
- 7 Helpful Links
Setting up Django
Here's how to set up a Django site under your account using Passenger WSGI, which is recommended. Instructions for completing a FastCGI setup are still available at Django FastCGI, but are not recommended — FastCGI is significantly slower, and requires a more complicated setup process. Django can also run under CGI, which is even slower than FastCGI. Don't run Django under CGI.
Step 1 — Set up a shell account
If you don't already have a shell account set up for your domain, you must do so now. See Enabling Shell Access for further instructions.
Step 2 — Configure your domain
You'll need to set up your domain to use Passenger. You can do so by following these steps:
- Open the Manage Domains section of the panel, and start editing your domain.
- Scroll down to the "Users, Files, and Paths" section. If your web directory does not end with "/public", add that to your web directory.
- Once you have done so, scroll down to "Web Options". Turn on the "Passenger" checkbox.
|Note:||If you currently have files under the domain, you must move them into the new "public" directory to make them appear!|
Step 3 — Create a database
Any Django site needs a database. If you don't have one prepared already, you can create one through the panel at MySQL Databases. We strongly recommend creating a database just for Django (rather than sharing a database with other applications), as Django does not use a prefix on its table names.
Step 4 — Run the Django setup wizard
SSH into your server, cd into the directory for your application (i.e, the directory which contains your site's public directory, not the public directory itself), and run these commands:
wget http://wiki.dreamhost.com/django-setup.py python django-setup.py
This script will lead you through rest of the the process of setting up your application.
Migrating existing sites from FastCGI to Passenger
Reorganizing your file structure
We recommend reorganizing your directory structure when you migrate to Passenger. If you used the old instructions then you probably have a django_src directory and a django_projects directory. One possible improvement puts everything under a single "django" directory:
/home/username/django/ source (your django svn checkout, or skip it and use Dreamhost's site-package of Django) projects applications (any reusable applications shared between projects)
Assuming you had the old django_src and django_projects directories, the following would move things around, starting from your home directory:
mkdir django mv django_src django/source mv django_projects django/projects mkdir django/applications
Migrating an existing FastCGI site
- Follow the steps above to change your web directory to end with "/public" and enable Passenger on the domain.
- Move your static media from its old location to the new public directory.
- Adjust the settings.py for your project to point to the new location for the media directory.
- Remove the mod_rewrite lines from the .htaccess file in your old web directory, the one that now contains the "public" directory. You'll probably just want to remove the file altogether and create a new one under "public" for the static media, as shown below.
- Create a passenger_wsgi.py script in the directory above "public", making sure to add paths to the Django projects and applications directories. If you're using your own Django svn checkout then add the path to that as well. Be sure to replace "username" with your user name and "projectname" with your project name!
import sys, os if sys.version < "2.4": os.execl("/usr/bin/python2.4", "python2.4", *sys.argv) sys.path.insert(1, "/home/username/django/source") sys.path.insert(1, "/home/username/django/applications") sys.path.insert(1, "/home/username/django/projects") os.environ['DJANGO_SETTINGS_MODULE'] = "projectname.settings" from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
|Note:||For Django versions up to 1.6, you may use 'django.core.handlers.wsgi' instead.
import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
The newer syntax was added in Django 1.4 and is required as of 1.7.
The version check is necessary to force Passenger to use Python 2.4 (for decorator support) on some older servers which default to Python 2.3.
If you were using the locations in the previous Django FastCGI instructions, then you would add only the following to your path instead:
sys.path.insert(1, "/home/username/django_src") sys.path.insert(1, "/home/username/django_projects")
Custom Python and Django install
The following covers the process of installing python (2.7.7) and django (1.6.5) versions in order to be on the same versions as the one you run in development.
Please refer to this stack exchange article for more information.
Building a custom python install
SSH into your shell account
cd ~ mkdir tmp cd tmp wget http://www.python.org/ftp/python/2.7.7/Python-2.7.7.tgz tar zxvf Python-2.7.7.tgz cd Python-2.7.7 ./configure --prefix=$HOME/opt/python-2.7.7 make make install
This will install your local version of python to /home/<username>/opt/python-2.7.7
Add to your path in order to use this version of python over the system default:
You can also add this line to the .bashrc and/or .bash_profile file in your home directory to make this permanent. (see here for info on the difference) Other shells are available, but I'll assume if you've changed yours you really know what you're doing!
Check which version of python you're now using:
In order to install various python packages, and Django in particular, then you'll want pip.
curl https://bootstrap.pypa.io/get-pip.py > ~/tmp/get-pip.py python ~/tmp/get-pip.py
(Using curl here rather than wget, as it handles the secure site (https) better)
Finally in order to "freeze" the package versions for your website (so they don't automatically update when you set up another site at a later date), you'll likely want to install virtualenv.
pip install virtualenv
Setting up your Django site
In the Dreamhost Panel set up a new fully hosted domain with a web directory set to /home/username/
domain.name/public and enable Passenger.
Once the new directory has been created on your server, set up a new virtualenv:
This will create a local copy of your environment specific to this website.
While working on this website, you should activate the local environment in order to make sure you're working with the right versions of your tools and packages:
Now you can install Django and any other required packages (e.g. MySQL-python if you're going to use a MySQL database) for your website using pip:
pip install Django pip install MySQL-python
Now you can create your Django project:
cd $HOME/<domain>/ python env/bin/django-admin.py startproject <projectname>
In order for Passenger to pick up your project, you need to create a
passenger_wsgi.py file within your site's top level directory (/home/username/domain).
The file should contain the following:
import sys, os cwd = os.getcwd() sys.path.append(cwd) sys.path.append(cwd + '/projectname') #You must add your project here #Switch to new python if sys.version < "2.7.7": os.execl(cwd+"/env/bin/python", "python2.7", *sys.argv) sys.path.insert(0,cwd+'/env/bin') sys.path.insert(0,cwd+'/env/lib/python2.7/site-packages/django') sys.path.insert(0,cwd+'/env/lib/python2.7/site-packages') os.environ['DJANGO_SETTINGS_MODULE'] = "projectname.settings" from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
Be sure to replace the two instances of
projectname with your actual project name!
Within the projects setting file, found at
projectname/projectname/settings.py you will find that the
STATIC_URL is probably configured to
Add another line to set the location on the server of the actual static directory:
STATIC_ROOT = os.path.dirname(BASE_DIR) + '/public/static/'
This will be the location where Django will put all of your static files - you shouldn't put stuff here manually as it gets overwritten. Run the collectstatic command now to set up the static items for the admin interface:
cd $HOME/<domain>/ projectname/manage.py collectstatic
Finally you should set up your database as required within the settings.py file - the default is to use sqlite3, which maybe suitable for the smallest of sites, but it's likely you'll want to set up a mysql database. Once configured, run a syncdb:
Set up a superuser as and if required.
Et voila! You should now see the standard Django holding page at your domain and be able to access the admin console at /admin/.
- If your application isn't working, double-check usernames, passwords, database names, and hostnames in the settings file.
- If you make changes to the code, such as working through the official tutorials, and they don't seem to work, make sure to kill any existing python processes and reload the page.
- If you modified your application and your changes do not seem to be reflected, you may need to notify Passenger about your change by creating or modifying ~/example.com/tmp/restart.txt:
Passenger looks for this file and reloads the application when this file is modified.
- If you're using shared hosting and your changes do not seem to be reflected, you can notify Passenger about your change this way: touch passenger_wsgi.py
- If you installed a custom version of python in your directory and you'd like to use it, add the following to your passenger_wsgi.py file:
if sys.hexversion < 0x2060000: os.execl("/path/to/your/copy/of/python2.6", "python2.6", *sys.argv)
- If you're getting meaningless 500 pages even though you have DEBUG enabled in your Django app, you're probably running into a Passenger problem dealing with errors; see Passenger_WSGI#500_Errors_with_Passenger_WSGI_Workaround for help on getting around it.
- If you're following the Django tutorial or migrating an existing project you may get "Premature end of script headers" in your http error.log. This may be due to the Passenger file not including your project directory in path. One correct solution is to open passenger_wsgi.py and add the following:
The following is a sample of how to send an email using a dreamhost server.
In your settings.py file:
EMAIL_HOST = 'mail.yourdomain.com' EMAIL_HOST_USER = 'firstname.lastname@example.org' EMAIL_HOST_PASSWORD = 'yourpassword' SERVER_EMAIL = DEFAULT_FROM_EMAIL = EMAIL_HOST_USER EMAIL_PORT = 587 EMAIL_USE_TLS = True
Shared environment forces users to use some tricks to improve overall performance of web applications. Django provides many ways to do it:
- Use Django's excellent cache facilities --- make sure your web application uses Filesystem caching or Database caching. In memory caching doesn't work very well in shared environments. And we don't have memcached yet.
- Use appropriate Django's middleware --- specifically you should check out Cache middleware (described in Cache documentation), GZip middleware to improve bandwidth utilization (works well with cache to amortize expenses on data compression), and Conditional Get middleware to reduce bandwidth even more (works well with cache).
- Enable caching of all your static files.
- Enable compression of compressible static files (like .css, .js, .html, and so on).
The latter two can be achieved by placing a specially crafted .htaccess in top static file directories (like media/, appmedia/). The one I use is here:
|Warning:||The above file works only for Apache 2.0! If you still use Apache 1.3, please talk to DreamHost support to switch you over to Apache 2.0.|