Wednesday, June 27, 2012

Journey in Python/Django - Hello World - Part 2


Here are my ongoing adventures in configuring a base Python/Django application. 
First let's give you some background on my development environment.
I am using a MacBook Air running Lion. 
I have Python 2.7 installed.
For my Python/Django editor I use the Jetbrains PyCharm IDE.
The first thing I want to do is to create a Hello World application on my local machine. I have a folder for all my PyCharm projects so I will create the application there.
So the first steps are with a Terminal Window:
- Change directory to my PYCharmProjects folder
mkdir helloworld 
The first thing I want to do is to isolate this application from modules used in other applications. For that we turn to VirtualEnv. Chris Scott has a great introduction on installing and configuring VirtualEnv.
After installing VirtualEnv I then proceeded to setup VirtualEnv with no dependency on the currently installed system site-packages for python. This is the default behavior for current releases of VirtualEnv but if you want to be explicit use this command:
virtualenv --no-site-packages helloworld
cd helloworld
source bin/activate
This activates VirtualEnv. You should see the system prompt add (helloworld) at the front of the prompt. One advantage of running in the VirtualEnv mode is that you don't need to use sudo to make changes since you will only be changing this instance and not your base system configuration.
Since we are starting with a bare bones Python installation using Virtualenv we need to install all the modules we often forget about. Let's start with the obvious one: django
pip install django
This lets me then run the startproject function of django-admin.py:
python bin/django-admin.py startproject helloworld
This will create a helloworld folder inside the existing helloworld folder.
- helloworld
-- bin
-- helloworld
   --- helloworld
       ----- settings.py
       ----- urls.py
       ----- wsgi.py
   --- manage.py
-- include
-- lib
Let's make sure we can run Python. 
cd helloworld
python manage.py runserver
if you see something like this then your python server is running on your local machine:
=========================================
Django version 1.4, using settings 'helloworld.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
=========================================
By default your python server will run on 127.0.0.1 / localhost using port 8000
If you go to your browser and go to http://localhost:8000 or http://127.0.0.1:8000 you should see something like this:
Great! We have a working server. We can shut it down for now and continue with our configuration efforts.
Go ahead and use CONTROL-C to quit the server.
While still in the helloworld/helloworld folder I now want to make a few folders to prepare our overall application structure:
mkdir apps
mkdir config
mkdir db
mkdir mainstatic

mkdir mainstatic/img
mkdir mainstatic/js

mkdir mainstatic/sass
mkdir mainstatic/stylesheets
mkdir templates
Next step is to fire up PyCharm and open up the helloworld/helloworld application.
Since we will be uploading this application to github we want to make sure any spurious files are not included. The main thing here is to exclude any .pyc files and also the database. Our database will be stored here: db/db.db
To prepare for github we will create a .gitignore file in the helloworld/helloworld folder (alongside manage.py)
The .gitignore file contains the lines:
*.pyc
db/db.db
I also create a README.md file to store read me instructions for the app.
I also add a requirements.txt file in the config folder. This is used to record all of the modules installed that support this app. At the moment this has just one entry: django
The requirements.txt file is important. When you perform a fresh install of the application you can go to the helloworld folder that contains manage.py and issue the following command to install all the necessary modules:
sudo pip install -r config/requirements.txt 
As you add new modules make sure you keep this file up to date and add any configuration notes to the README.md markdown file.
Cascading Style Sheets
We will want to use CSS to style our web pages so rather than code directly in CSS we will use the SASS framework. We therefore need a pre-processor that will compile from SASS to CSS whenever we make changes. Compass is a great tool that accomplishes this feat.
Compass uses Ruby so we use the gem install process to install it:
sudo gem install compass
We now need to go and make some changes to our settings.py file. You will find this in the helloworld/helloworld folder. The one below the manage.py file.
Settings.py
This file does as it's name suggests. It is used to store variables and configuration data used in the application.
Let's work our way though it.
First we want to add in some data collection that enables some auto configuration:
import os
import sys
import tempfile
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
APPS_DIR = os.path.join(BASE_DIR, 'apps')
sys.path.insert(0, APPS_DIR)
Change ADMINS = to add your name and email contact information.
We want to use the BASE_DIR setting to help us define the absolute path for the database. Therefore we add this line in front of the DATABASES section:
DBPATH = os.path.join(BASE_DIR, 'db/db.db')
We will be using sqlite3 so we need to change the database information accordingly:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': DBPATH,                  # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}
To set our Time Zone we need to look up our local time zone here: http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
Update the STATIC_ROOT setting:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Add a MAIN_STATIC_ROOT setting:
MAIN_STATIC_ROOT = os.path.join(BASE_DIR, 'mainstatic')
Add the following line to the STATICFILES_DIRS setting:
MAIN_STATIC_ROOT,
In our case we want the Eastern Time Zone. So we will use New York:
TIME_ZONE = 'America/New_York'
Add this line to the TEMPLATE_DIRS setting:
    os.path.join(BASE_DIR, 'templates'),
COMPASS configuration in settings.py
We need to make the following additions and changes to settings.py in order for compass to operate:
Then add the following lines:
COMPASS_INPUT = MAIN_STATIC_ROOT + '/sass'
COMPASS_OUTPUT = MAIN_STATIC_ROOT + '/stylesheets'
COMPASS_STYLE = 'compact'
COMPASS_REQUIRES = (
    'ninesixty',  # 960.gs Grid System
    )
Let's Get Compass running... 
compass version
this will confirm that Compass is installed.
next run:
compass create ./mainstatic
This will create the SASS and stylesheet files for the project.
The compass configuration file is config.rb in the mainstatic folder.
When you want to use the CSS stylesheets add the following to your template files:
 
 
 
You can configure Compass to watch for changes to your SASS files. To do this:
- Open a new terminal window
- cd to the mainstatic sub-folder
compass watch
You should see this message:
>>> Compass is polling for changes. Press Ctrl-C to Stop.
You can now minimize this window. When SASS files change the CSS files will be automatically updated.
In part 3 we will look at getting the basic home page working and then look at how we can install Twitter's Bootstrap CSS framework and apply some styling to the home page.