PyBc/Django

Web Development: An introduction to Django

Python Boot Camp 2010 - Django Break-Out - January 13

Presented By: Nico Preston

References

This tutorial is modified from Blog for the Impatient by Forcier, Bissex, and Chung. These authors have made numerous outstanding contributions to the Python Community. This book is an excellent resource for learning Django. There is also an excellent primer on python in Chapter 1. The book can be accessed by UW students, faculty, and staff, through Safari Books Online via UW Library Electronic resources.

Installing Django

This tutorial assumes you've followed the Python installation instructions for the earlier in this Python Bootcamp InstallingPython .

It is easiest to install Django from source. Even better, by accessing the SVN (subversion) releases you'll get the most up-to-date version of Django for development applications. For production applications you may want to download and freeze a version (e.g. virtualenv) to ensure compatibilities.

Here is how to acquire Django from the command line (Linux, Mac, and Windows):

Linux

Note: you may need to sudo

Use your package manager

apt-get django

OR Download and build from source

cd desktop 
wget http://www.djangoproject.com/download/1.1.1/tarball/ 
tar xzvf Django-1.1.1.tar.gz 
cd Django-1.1.1
sudo python setup.py install

export PATH=/usr/local/lib/python2.6/dist-packages/django/bin/:$PATH

Mac

Note: you may need to sudo

OS X command line (Enthought Python installation)

cd /Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6
sudo svn co http://code.djangoproject.com/svn/django/tags/releases/1.1.1/django
sudo ln -s /Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6/django/bin/django-admin.py /usr/bin/django-admin.py

OS X command line (Factory/Built-in Python installation)

cd /Library/Python/2.6/site-packages/
sudo svn co http://code.djangoproject.com/svn/django/tags/releases/1.1.1/django
sudo ln -s /Library/Python/2.6/site-packages/django/bin/django-admin.py /usr/bin/django-admin.py

OS X via Browser Download the tarball. Then double click download.

Windows

1 - Install Subversion

[Subversion]

Choose Apache 2.2 - if you don't know which one you have/will have

For a different [version]

2 - Install Django 1.1.1

C:\> cd C:\Python26\Lib\site-packages
C:\Python26\Lib\site-packages> svn co http://code.djangoproject.com/svn/django/tags/releases/1.1.1/django django

3 - Move admin to scripts directory

Make a copy of django-admin.py (located in django\bin) and put it in C:\Python26\Scripts

ALTERNATIVE

requires: [Exemaker]

cd C:\Python26\Lib\site-packages
svn co http://code.djangoproject.com/svn/django/trunk/django

cd django\bin
exemaker django-admin.py

Your first Django app: A lab note manager

Django Architecture

Diagram of django architecture from linfiniti.com

Image source: [Linfiniti Geo Blog]

The final product of this tutorial

Screenshot of the final "My Lab Notes" application

Build project and application

Restart your terminal for all OSs!! This will ensure it can find django-admin.py

Use django and python commands to build the file directories for your project (mysite) and application (lab). First navigate to the Desktop.

#Macs & Linux
cd ~/Desktop/
#Windows 7
cd \Users\YOUR-ACCOUNT-NAME\Desktop

You can move this project around later to whichever directory you like. Everything will be contained within the project folder.

django-admin.py startproject mysite
cd mysite
python manage.py startapp lab

Now tell the project to look for the lab application. Add the application (lab) to INSTALLED_APPS in settings.py (at the bottom) and don't forget the trailing comma (this is a tuple).

	'mysite.lab',

Now test the success of your project installation by launching the built-in development server. Note: you must be in the mysite directory.

python manage.py runserver

Then visiting the site on local host through your web browser.

e.g. http://127.0.0.1:8000/

You should receive a page that says 'It worked''

"It worked" screenshot

Configure database

Edit settings.py

MAC/Linux (file: mysite/settings.py)

DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'lab_db.sqlite3'            

Win32 Create a directory for dbase

(file: mysite/settings.py)

DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'lab_db.sqlite3'      

Create models for database

Django uses an Object Relational Mapper (ORM) to manage your database. You describe the tables in your models file, then they will be converted into SQL create table commands by Django when you syncronized the database. This helps you deploy the application on any system. The SQL commands used will correspond with the database type you declared in your settings file, e.g. MySQL, SQLlite, or PostgreSQL.

(file: mysite/lab/models.py)

from django.db import models                                                      
                                                                                
class LabPost(models.Model):                                                    
    title = models.CharField(max_length=150)                                    
    body = models.TextField()                                                   
    timestamp = models.DateTimeField()           

Synchronize the database

When you synchronize the database, Django will update the database tables and fields according to your models.py file. Note you need to be in the project (mysite) directory.

cd mysite
python manage.py syncdb

At the prompt create superuser settings:

Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'nico'): pybc
E-mail address: pybc@pybc.com
Password: pybc

If you make a mistake, it can be easiest to delete the SQLlite database file and resynchronize.

Configure admin app

Add admin to the application list in the settings file (file: mysite/settings.py)

    'django.contrib.admin',

Uncomment the following two lines in urls.py to enable access to the admin via the browser's URL:

(file: mysite/urls.py)

# Uncomment TOP
from django.contrib import admin
admin.autodiscover()

# Uncomment BOTTOM
(r'^admin/', include(admin.site.urls)),

The end-product will look something like this:

(file: mysite/urls.py)

from django.conf.urls.defaults import *                                                                 
from django.contrib import admin                                                
admin.autodiscover()                                                            
                                                                                
urlpatterns = patterns('',                                                                         
    (r'^admin/', include(admin.site.urls)),                                     
)                                         

Register lab with the admin

You need to tell the admin which applications it will manage. This is done through the models.py file in each application.

(file mysite/lab/models.py)

# Add to TOP
from django.contrib import admin

# Add to BOTTOM
admin.site.register(LabPost)

Now re-sync the database:

cd mysite
python manage.py syncdb

Check it out on localhost, e.g. http://127.0.0.1:8000/

What does the error message tell you

OK ...

Try adding the word admin after the dash in the URL ( http://127.0.0.1:8000/admin).

After you log-in:

Username: pybc
Password: pybc

It should look like this

Screenshot of admin screen with LabPost

Add some notes

Your website is now ready to store data. Try adding notes from the admin interface. Notice how they are listed in the LabPost? section. We'll improve the format of the listings next.

Pretty up the Admin

Let's provide more information about each note in the table of contents. Edit models.py to include the class LabPostAdmin?, then register it with admin:

(file: mysite/lab/models.py)

from django.db import models                                                    
from django.contrib import admin                                                
                                                                                
class LabPost(models.Model):                                                    
    title = models.CharField(max_length=150)                                    
    body = models.TextField()                                                   
    timestamp = models.DateTimeField()                                          
                                                                                
class LabPostAdmin(admin.ModelAdmin):                                           
        list_display = ('title', 'timestamp')                                   
                                                                                
admin.site.register(LabPost, LabPostAdmin)  

Configure the Public side (templates)

Now let's make the website look like a real application. We don't want users logging on the the admin, that's just for the webmaster and collaborators.

1) Create template 2) Edit view 3) Setup URL

1) Create template

Build a template directory to house the templates:

cd mysite
mkdir templates
cd templates
mkdir lab
cd lab

Build a template that loops through each LabPost? and displays the title, time, and body in HTML tags.

(file: mysite/templates/lab/archive.html)

{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.timestamp }}</p>
<p>{{ post.body }}</p>
{% endfor %}

Add a reference to the location of your template directory to your project settings file:

(file: mysite/settings.py)

TEMPLATE_DIRS = (
    'YOUR_DIR/mysite/templates',   
)  

2) Create View

The view will send the fields from the database to the html template for display.

(file: mysite/lab/views.py)

from django.template import loader, Context
from django.http import HttpResponse
from mysite.lab.models import LabPost

def archive(request):
    posts = LabPost.objects.all()
    t = loader.get_template("lab/archive.html")
    c = Context({ 'posts': posts })
    return HttpResponse(t.render(c))

3) Create URL in mysite to redirect to URLconf (urls.py) in lab

(file: mysite/urls.py)

# ADD
    (r'^lab/', include('mysite.lab.urls')),

Create generic URLconf for the application

(file: mysite/lab/urls.py)

from django.conf.urls.defaults import *
from mysite.lab.views import archive

urlpatterns = patterns('',
    (r'^$',archive),
)

Adding niceties through templating

Now let's make this look more like a website by adding some formatting through css. In a production site you would store the CSS in a stand-alone file, that way you only need to edit one file to make changes throughout the site.

Create a base template for the overall look of the application.

(file mysites/templates/lab/base.html)

<html>                                                                                              
<style type="text/css">                                                                             
body { color: #efd; background: #453; padding: 0 5em; margin: 0 }                                   
h1 { padding: 2em 1em; background: #000 url(http://hackerwithin.org/cgi-bin/hackerwithin.fcgi/raw-attachment/wiki/ThwLogo/thwlogo-dark-small.png) no-repeat 0; text-indent:250px}                      
h2 { color: #000; border-top: 2px dotted #000; margin-top: 2em }                                    
p { margin: 1em 0 }                                                                                 
</style>                                                                                            
<body>                                                                                              
<h1>My lab notes</h1>                                                                               
{% block content %}                                                                                 
{% endblock %}                                                                                      
</body>                                                                                             
</html> 

Now extend the base template with a new customized template for the lab notes. Edit the archive template.

(file mysite/templates/lab/archive.html)

{% extends "lab/base.html" %}
{% block content %}
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.timestamp }}</p>
<p>{{ post.body }}</p>
{% endfor %}
{% endblock %}

Finished

Screenshot of the final "My Lab Notes" application

Attachments