Django Lab - Furman



Django Lab

William Hendrix

November 2006

Introduction

Django is a web design framework based on the programming language Python. Advantages to using Django are its built-in functions for database access, its control over the exact appearance of your site’s URLs, its powerful template system, and its automatically-generated admin pages, to name a few.

In this lab, we will be creating an app, which is not an entire website (or project), but only a feature of a project which, ideally, should be written in such a way that it can be moved from one project to another with little or no modification. Our app will be a naïve implementation of a blog.

Setting Up

First, open the command prompt (Start Menu > Run… > cmd), and navigate to the Django projects directory (cd\Django-0.95\projects). Now, to begin your project, type django-admin.py startproject projectname, then navigate to the newly created project directory with cd.\projectname. Type dir, and notice that django-admin.py has created four files for you: __init__.py, which declares this as a Python package; settings.py, which is where you will enter some of the project-specific settings; manage.py, an executable like django-admin.py which will simplify some aspects of site management; and urls.py, a file we will edit later which defines the URL layout of your site.

Start your blog app with the command manage.py startapp blog. This will create a blog subdirectory in your project, with the files __init__.py, models.py, and views.py, which we will be handling later in the lab. For now, open the file settings.py in your favorite word processor (I recommend notepad or notepad2), and make the following additions:

• Enter mysql between the single quotes following DATABASE_ENGINE =.

• Enter the database name, host, and port as well as your username and password in the appropriate places. If you followed the installation as written, the database name should be test, the username should be root, the password should be your root password, and the other fields should be left empty.

• Add ‘c:/Django-0.95/projects/projectname/blog’ (note, these are all forward slashes) to the TEMPLATES_DIRS setting.

• Add ‘blog’ to the INSTALLED_APPS setting. Make sure all of the apps are separated by commas.

• For simplicity’s sake, remove ‘django.contrib.auth’ from the INSTALLED_APPS. This app controls the admin authentication, which we will not be implementing here.

You will notice that comments in Python begin with # and continue until the end of the line. You may also notice the lack of semicolons.

Your next tasks will be to set up the URL structure for the project (in urls.py) and the project models (in blog/models.py). After this you can tackle the more complex templates and views.

To test your finished (or partially finished) app, type manage.py runserver from the blog directory and you will be able to view your work at .

URLs

Within Django, URLs are not instructions for locating a file stored on the web server, but are instead instructions for which Python function will be called, and with what parameters. These functions are called views, and each one will return an HtmlResponse object, which will be displayed by the browser.

The determination of which view to call is based on the urlpatterns object defined in urls.py. A given URL is stripped of its domain name, and then matched to one of the patterns in the urlpatterns. These patterns are defined in the first element of each tuple in the patterns declaration. They are regular expressions, which have a number of interesting properties, but we will only need a couple of these. Your patterns should begin with r‘^ and end with ’. You may use a $ at the end of the expression to indicate that this should be the end of the URL name, but this is not necessary (‘hello’ would match r‘^he’ but not r‘^he$’). All slashes and alphanumeric characters are treated as literals. As an example, a pattern that would map the URL blog/ to a view called show is (r‘^blog/$’, ‘blog.views.show’).

It is also possible to pass parameters to the views based on the given URL. For our purposes, we will need to extract the post id number from the URL. The syntax for capturing an integer is including (?P\d+) at the appropriate point in the regular expression. The variable varname will then be passed as an extra parameter to the view, with the captured value.

Once a matching pattern is found, the view that is the second element of the tuple is called. All of the views for our app will be of the form ‘blog.views.viewname’. For our blog app, we will need five views: one for viewing recent posts, one for viewing the comments on a post, one for displaying a form to create a new post, one to actually add the post to the database, and one to add a new comment to the database. (Viewing comments and adding a comment will require a post id number.)

This lab demonstrates some of the power of the URL support in Django, but is by no means exhaustive. To find out more, go to documentation/urls.

Models

All of the models for the project are stored in the models.py file, so open this file up in a word processor. A Django model is a Python class that, more or less, describes a single table in the database. Each model keeps track of all of its instances, each of which represents a tuple in the database. The syntax for declaring a new model is:

class Entry(models.Model):

All of the fields, functions, and inner classes of the model should follow this declaration and be indented exactly four spaces (no tabs!). Note: Django automatically includes an id field as a primary key for each model (which can also be referenced as pk), so you don’t need to define it yourself.

One field that is important for a blog entry is a title, which could be declared:

title = models.CharField(maxlength = 50)

Note the four spaces and lack of a semicolon. Not to insult your intelligence, but this statement declares a field called title, of type models.CharField, which will store up to 50 characters for a title.

Other important field types are models.DateTimeField, models.IntegerField, models.ForeignKey, and models.ManyToMany. Unlike CharField, DateTimeField and IntegerField don’t require any arguments to instantiate; however, both ForeignKey and ManyToMany require the name of the class as a parameter. ForeignKey defines a one-to-many relationship between models—for example, if we were designing a poll with a Poll class that should be associated with many different Choice objects, we would include:

poll = models.ForeignKey(Poll)

in the Choice class. This declaration would also implicitly create a field in the Poll class called choice_set, which is an array of all Choice objects associated with the particular Poll. (The name choice_set is derived from appending “_set” to the lowercase name of the class.) ManyToMany is nearly identical but allows many-to-many relationships, such as one where an article can have multiple authors and authors can write multiple articles.

Functions of a class are defined as such:

def __str__(self, otherparams):

where __str__ is the name of the function, and the list of parameters is inside the parenthesis—all class functions have a first argument that contains the instance of the class that the method is called on. All of the statements that belong to this function should follow the declaration and be indented an additional four spaces. __str__() is an important function in Python; it’s equivalent to toString() in Java and defines the default for how an object should be displayed. In the context of Django, this is important for the automatically-generated admin pages, and even though we will not be implementing admin pages for our blog app, you should define this function for all of your classes. Since the title of an entry is a good way to represent that entry,

return title

would be a reasonable implementation of __str__() for the entry class.

You should define two models for this app: one that represents a blog entry, and another that represents a comment made on an entry. A blog entry should keep track of its title, author, and text (all strings), as well as the time it was posted. A comment should keep track of its author, text, and date, as well as the entry with which it is associated.

Once you’ve finished writing your models, return to the command prompt and type manage.py syncdb. This will cause Django to analyze your models.py file and add appropriate tables in the database specified in settings.py.

Templates

For our blog app, we will be using Django’s template system. Templates are a hierarchical way to organize how your web application will be displayed. By hierarchical, I mean that once a template has been defined, it can be called by itself, incorporated as part of a larger template, or extended to make a more specific template. For example, you can define a template that defines how to display a single blog entry, and then utilize that template everywhere you need to display a blog entry*.

*You will be doing this. (

A Django template is a HTML file which describes what a user will actually view when he or she visits your site. A template can describe an entire HTML page, but the real power of the template system lies in a template’s ability to describe a portion of a page that can be reused in several places in a web site.

Templates follow the same conventions as a standard HTML page, without the requirement to be an entire page—thus, many templates, especially those belonging to an app rather than a project, do not include or tags. Templates also have the ability to break into and out of Python code, with {% codefragment %}, and to echo out the value of Python variables, with {{variable}}. Later, we will see the function which passes in the Python variables, along with their names.

The only Python functions we will be using in our templates are the for loop and the if statement. The syntax for these are:

{% for variable in list %}

{% endfor %}

{% if conditionOrVariable %}

{% else %}

{% endif %}

Also, while inside the for loop body, you have access to the forloop.counter variable which contains the number of the current iteration.

As I mentioned earlier, Django allows you to define pieces of HTML pages that can be used multiple times. The syntax for referencing another template is:

{% include “template” %}

For this lab, you will create four templates: one for displaying a single entry, one for displaying a list of the five most recent entries, one for submitting a new entry, and one for displaying the comments associated with a blog entry. Templates should be saved as .html files in the blog directory.

In displaying the single entry, choose any sort of format that suits your taste. It should, however, display the title, author, date, and text.

In displaying the recent entries, you should include with each a link to its comments page, and you should include somewhere on the page a link for creating a new entry.

The template for submitting a new entry should be a form, using method=“post”. Two form elements you may wish to use are and . You should not need any form elements for selecting a date or time, as the entry should be tagged with the current date/time, and remember that when a form is submitted, the values of the form elements are accessed from the POST data by the name attribute of the associated form element.

In displaying the comments, you should first redisplay the blog entry at the top, and then list the comments. You may define a separate template for displaying a single comment, but this is not necessary. Below the comments should be a form for submitting a new comment, which should be similar to the new post form, without the title field.

The template system in Django is extremely powerful, and we have only scratched the surface of all that it can do. Visit documentation/templates/ to learn more.

Views

Views in Django are essentially functions that take an HttpRequest object and possibly other parameters and return an HttpResponse object (or an HttpResponseRedirect object). As a reminder, we will need five views for our application: one for displaying recent posts, one for displaying a post with all of its comments, one for composing a new post, one for adding that post to the database, and one for adding a new comment to the database. Be aware that for viewing comments and posting a new comment, your function will need to know which blog entry the comment(s) relate to, so include an entry id as an additional parameter—we saw how to generate this in the URLs section.

Django also includes a generic view system that abstracts out several common tasks to reduce coding, but we will not be using that for our app. You can find out more about generic views at documentation/generic_views.

The first issue with creating a view is importing the Python functions you will need to implement your views. You may have noticed the line

from django.db import models

at the top of the models.py file. This was very convenient at the time, since all of our external references, like models.CharField and models.DateTimeField, were all located in models. However, the views we are writing will be more complicated. Here are the appropriate import statements, and a brief description of what they do:

from django.http import HttpResponseRedirect

• HttpResponseRedirect is an object that, rather than returning a web page in the form of an HttpResponse object, will cause the browser to visit the indicated URL.

Example usage:

def redirectExample(request):

return HttpResponseRedirect(‘blog/’)

from django.shortcuts import render_to_response, get_object_or_404

• render_to_response is a convenient shortcut method that will allow you to pass “parameters” to a template, render that template, and return the result as an HttpResponse object. Be sure that the variable names that appear here agree with those in your templates.

Example usage:

def requestExample(request):

return render_to_response(‘example.html’, {‘variableInHTML’:replacementVariable, ‘otherVariable’:otherReplacement})

• get_object_or_404 is a shortcut that permits searching of the database for an object, returning the object if it is found, or raising a Http404 exception if it is not.

Example usage:

def getExample(request, widget_id):

w = get_object_or_404(Widget, id = widget_id)

#...

The first argument of get_object_or_404 is the class of the object, and the second is the condition that will be used in searching. For our purposes, id = idvar (or pk = idvar) will be sufficient, but Django does support more complex searches, as well as a get_list_or_404 method, which can return an array of search results.

from projectname.blog.models import class1, class2

Replace class1 and class2 with the entry and comment models you wrote. You should need to reference both.

from datetime import datetime

• datetime contains the Python functions related (not surprisingly) to dates and time. For the purposes of this app, we are only interested in the function datetime.now(), which returns a datetime object with the current time.

Example usage:

def dateExample(request):

return render_to_response(‘time.html’, {‘time’:datetime.now()})

A second issue is how to retrieve the five most recent articles from the database. To spare you the details, the command is

variablename = class1.objects.all().order_by(‘datefield’)[:5]

where class1 is the name of the blog entry class, datefield is the name of the DateTimeField in the blog entry class, and variablename is the name of the variable in which to store the results. The variable type here is a QuerySet. QuerySets are interesting in that a SQL query is not actually performed until an element of the QuerySet is accessed—QuerySets are lazy. (Hint: accessing the elements of a QuerySet can be accomplished by a for loop within a template.) More on QuerySets and managers and such can be found at documentation/db_api/.

Lastly, there are three new techniques associated with creating a new blog post or comment. First, the syntax for instantiating a new variable is

variablename = classname(param1 = value1, param2 = value2, …)

where variablename is the name of the new variable, classname is the name of the class to instantiate, and param1, param2, etc. are the fields of the class, which should be initialized to value1, value2, etc. Second, manipulations to an instance of a model (including creating a new instance) don’t affect the database until the save() method is called…this sort of mistake is difficult to debug, so don’t forget it. Third, accessing POST data is as easy as referencing request.POST[‘variable’], where request is the name of the HttpRequest variable that is passed into the view function, and variable is the name of the POST data to retrieve (like ‘author’, ‘title’, etc.).

Wrapping it up

Copy the contents of your blog folder into a folder that includes your last name, and submit this to the class In folder. If you’ve made it this far, congratulations!

Django Installation

These directions are for installing Python, Django, and MySQL on a Windows system. You will need administrator rights for the installations. If you are using Linux or OS X, or you want to install PostgresSQL, or you have any sort of trouble, other directions may be found at .

Install Python

The latest version of Python is 2.5 (which you can download at ), but I would recommend (for reasons I will reveal later) version 2.4.4, which you can find at . Installation is painless; just leave everything at the default.

Install a database

I chose MySQL for its relative familiarity. You can download MySQL at .

I would recommend the typical installation, and skipping sign-up. In the configuration wizard, I selected the standard configuration. On the next screen, leave everything at the default, but on the third, enter a root password and confirm it. Remember this password. Click Next and then Execute to finish.

You will also need a database for use with your Django project. MySQL automatically creates a database called “test”, but if this isn’t to your liking, you can download a utility like HeidiSQL () to manipulate your database. You may also find this useful for viewing and changing the contents of your Django database manually.

HeidiSQL installation is easy, but to use it, you’ll need to remember your root password from earlier.

Install the Python MySQL libraries

Here is the site I used: .

(Note that this executable is only compatible with Python 2.4, not version 2.5.)

If that doesn’t work, you may try starting at .

Install Django

The site for this is . After downloading the file, extract the contents (it’s a .tar inside a .gz, so you’ll have to extract twice). I extracted to C:, so my files all wound up in C:\Django-0.95.

After this, go to the command prompt (Start Menu > Run… > cmd). Navigate to the directory where you extracted Django (cd\Django-0.95, in my case) and type setup.py install. If this does not work, python setup.py install may.

setup.py should download and install setuptools for Python automatically for you, but in the event of an error (which happened to me when I had installed Python 2.5 rather than 2.4), you can download this as well at . Run this from the command line after downloading—it doesn’t need to be in your Python directory.

Details

The lab assumes that a projects folder exists in your Django directory, so typing md.\projects from that directory should create one.

It also assumes that django-admin.py is on your system path. First, try running django-admin.py. If this doesn’t work—‘django-admin.py’ is not recognized as an internal or external command, operable program or batch file—type:

path=%path%;c:\Django-0.95\django\bin

where you should replace Django-0.95 with the directory where Django is installed.

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download