Django Tutorial 2

From 118wiki

Jump to: navigation, search

Contents

Second Django Tutorial

Rather than a step-by-step recipe, let's consider where to go next, once you're successfully processed Django Tutorial 1. Here are some directions.

  1. The official Django Tutorial mentions a number of other hints and tricks; for example, you can use the database API interactively with the command
    python manage.py shell
    and experiment with queries, adding objects to your model, and updating object attributes.
  2. You can review other articles and blogs about Django; for instance, starting with this list. The trouble with this approach is that, while you will pick up interesting bits about Django, it may not be very directed for your project.
  3. You could download the "source" of web sites built with Django. For instance, many of the sites listed here offer downloads of all their customizations of settings.py, the views, templates, and so on. While it's interesting to look at the variety of these projects, they tend to be so elaborate that you get lost in all the code. These allow you to explore the code online rather than downloading it all.
  4. You can find articles that explain how Django components work, giving you the big picture, which is helpful for debugging and figuring out where things are done. I could not find a single place with a nice overall picture; this article is a good start, but you can spend lots of time studying without learning specific techniques.

So, rather than follow these, I recommend that you learn about some specific topics that might help you learn what Django you would need for your final homework project. Here, I list what I suspect would be most helpful.

Django Request and Response

As you have seen from the view specification (views.py), the basic logic of a website is to invoke a method in response to some HTTP request, identified by a URN or URL. The file urls.py specifies regular expressions for allowed URLs and what to do with these URLs. How does this work?

First, some background. You may have noticed that many URLs have parameters built into them, for instance

   http://22c118.cs.uiowa.edu/index.php?title=Django_Tutorial_2

specifies a file (index.php) and parameters, following '?' and given has keyword parameters. The programming interpretation of this is that a program (index.php) will be executed and passed parameters (given by the string following the '?'). Another technique for specifying parameters is just to use a path in the URL, for instance:

   http://22c118.cs.uiowa.edu/please/show/me/a/picture

This URL could be interpreted as a request to the "please" method, with parameter string "show/me/a/picture". Can Django do this?

Yes, and it is fully documented here, if you make sense of it. Further detail about how the URL-to-view procedure of Django works is documented here, along with examples of how the regular expression matching a URL in urls.py can parse out fields of the input URL and present them to your handler (method) defined in views.py.

If you want to use this technique in your homework, my advice is to try and modify Django Turorial 1 so that the "report" URL has some parameters. To do this, you would need to:

  1. modify the regular expression
    (r'^report/$', 'gtd.todo.views.status_report'),
    so that it doesn't need to be exactly "report/", but can be "report/" followed by parameters (in the language of regular expressions, $ is end of string). Again, look at this for more detail than you probably want to know.
  2. change the code in views.py so that status_report(request) does some processing of request (which is an HttpRequest object, see again here). You could just try "printing" request.path as a first step, where by "printing" I mean sending the value in the response, via the template -- which you would also need to modify to display a new output.
  3. if you want to go further with this, there are even standard parsing functions (Python has a cgi module you could import), but it's likely simpler just to parse things on your own for this homework.

Here is an example of using the request object. Suppose the following line has been added to urls.py:

  (r'^index', 'mydemo.medicine.views.index'),

This line says that any URL starting with "index" following the base URL, for instance

  http://l-lnx105.divms.uiowa.edu:9090/index/m/?q=99

would be an example of such a URL, will be processed by the index() method contained in views.py of subdirectory medicine, within the mydemo project. Let's take a look at how index might be written:

  from django.http import HttpResponse
  def index(request):
    pre = "<html><body><h1>path is</h1><p>"
    mid = request.path
    mid += "<h1>get_full_path() is</h1><p>" + request.get_full_path()
    mid +=  "<p><h1>META is</h1><p>"
    mid += str(request.META)  # show one attribute of request object
    pos = "</body></html>"
    return HttpResponse(pre + mid + pos)

This code is not a good example of formatting a response, in the sense that it bypasses using templates, just coding HTML directly. But the example does show how attributes and methods of the HTTP request object, as documented here, can be used. An example response looks approximately like this:

path is
/index/m/
get_full_path() is
/index/m/?q=99
META is
{'SSH_ASKPASS': '/usr/libexec/openssh/gnome-ssh-askpass',
 'wsgi.multiprocess': False, 'GROUP': 'faculty', 'RUN_MAIN': 'true',
 'HTTP_COOKIE': 'sessionid=5e6b863dd17c17fbc3789ba9486c1eb7', 'IA32ROOT': '/opt/intel_cc_x86_64', 'REMOTEHOST':
 'serv15.divms.uiowa.edu', 'SERVER_PROTOCOL':'HTTP/1.1',
 'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.3.4', 
 'HOSTTYPE': 'x86_64-linux', 'SSH_CLIENT': '::ffff:128.255.44.135
 50397 22', 'REQUEST_METHOD': 'GET', 'LOGNAME': 'herman', 
 'USER': 'herman', 'INPUTRC': '/etc/inputrc', 'PATH':
 '/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin', 'SSH_CONNECTION':
 '::ffff:128.255.44.135 50397 ::ffff:128.255.44.114 22', 'LANG':
 'en_US.UTF-8', 'KDEDIR': '/usr', 'TERM': 'xterm', 'SHELL':
 '/bin/tcsh', 'TZ': 'America/Chicago', 'REMOTE_HOST':
 'touring.cs.uiowa.edu', 'SERVER_NAME': 'l-lnx105.divms.uiowa.edu',
 'REMOTE_ADDR': '128.255.45.53', 'SHLVL': '1', 'SUPPORTED':
 'en_US.UTF-8:en_US:en', 'G_BROKEN_FILENAMES': '1', 'DISPLAY':
 'localhost:10.0', 'wsgi.url_scheme': 'http', 'SERVER_PORT': '9090',
 'OSTYPE': 'linux', 'CONTENT_LENGTH': '', 'VENDOR': 'unknown',
 'HTTP_KEEP_ALIVE': '300', 'HTTP_ACCEPT_CHARSET':
 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'PYTHONPATH':
 '/group/class/c118/py-lib', 'FPATH': '/opt/intel_fc_x86_64/include',
 'HOST': 'l-lnx105.divms.uiowa.edu', 'HTTP_USER_AGENT': 
 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.8) 
  Gecko/20061025 Firefox/1.5.0.8', 'HTTP_HOST': 
 'l-lnx105.divms.uiowa.edu:9090', 'SCRIPT_NAME': '',
 'wsgi.multithread': True, 'HTTP_CONNECTION': 'keep-alive',
 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_ACCEPT':
 'text/xml,application/xml,application/xhtml+xml,
  text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
 'wsgi.file_wrapper': , 'MACHTYPE': 'x86_64', 
 'wsgi.version': (1, 0), 'GATEWAY_INTERFACE': 'CGI/1.1',
 'wsgi.run_once': False, 'SSH_TTY': '/dev/pts/2', 'wsgi.errors': 
 ', mode 'w' at 0x2a9559b110>, 'HOSTNAME': 
 'l-lnx105.divms.uiowa.edu', 'HTTP_ACCEPT_LANGUAGE': 
 'en-us,en;q=0.5', 'wsgi.input': , 'PWD': 
  '/space/herman/mydemo', 'DJANGO_SETTINGS_MODULE': 
  'mydemo.settings', 'CONTENT_TYPE': 'text/plain', 
  'MAIL': '/var/spool/mail/herman', 
  'LS_COLORS': 'no=00:fi=00:di=00;34:ln=00;36:pi=40;33:',
  'QTDIR': '/usr/lib64/qt-3.3', 'HTTP_ACCEPT_ENCODING':
  'gzip,deflate', 'PATH_INFO': '/index/m/'}

Of course this is way more than you need for processing ordinary requests, but gives you an idea of all that Django makes available for request processing.

Site Architecture

You may have noticed that many web sites have links, forms, execute javascripts, and that the URL visibly changes as you navigate your way around the site. In Django terminology, this would translate to jumping from one method in views.py to another, or even jumping from one application (you can have more than just 'todo') to another. When you write templates, the links in those templates direct the browswer, upon user click, to send a request to another view. This can also be done with forms, which specify where and what type of HTTP request to send along with form data.

If this isn't clear to you, experiment with Django Tutorial 1 by writing another method (different from status_report), modifying urls.py to enable that method, providing another template, and so on, until you get the hang of it.

Forms

HTML pages can have forms for user entry; there are two basic types,

  1. those that result in HTTP GET requests, where the fields entered by the user result in keywords and values following '?' in the URL; these typically are limited to ascii values and some length limit, say 256 characters total in the URL.
  2. those that upload larger amounts of data and result in an HTTP POST request; they have no size limitation and can have arbitrary binary data, even included files sent by the browser.

You'll need to learn how to write HTML forms on your own, if you want to use forms -- you can start with Wikipedia's article on HTML forms or search for "HTML forms tutorial" using a search engine. Once you know the HTML, then you can put the HTML into a template and send it in a response. There is some mention of forms here (part of the official Django first tutorial), and also here. (near the middle of the document).

Persistent Data Operations

Most probably, you'll want to do some CRUD (that is, Create, Read, Update, Delete) operations on your modeled data. To do this, you should first study a little from Django's documentation, specifically, you need to read the Database API which has examples of reading, updating, querying and writing.

In Django, persistent storage is an area that holds objects, which area instances of the classes you define in models.py. Each object is essentially represented as a row in a table, and each row has to have a unique primary key (basically, just a sequence number) so that you can refer to it by an index. The indices are created automatically by Django, but you have to be aware of them.

To read an object in persistent storage, you "search" for it and get a query response with all the object that match your search. Then you can iterate through the items that match. Of course, if you happen to know that there is only one item (for instance, you search by primary key with a specific index value), this turns out to be overkill, but Django is general.

Once you have an object, you can update its fields and then "save" it to persistent storage. You can also create new objects, and delete objects.

Advice: as you start playing around with these Django operations, you might want to back up the sqlite database (nothing more than just making a copy of the database file).

Django also has facilities for transactions, but since we are using sqlite instead of a full-blown database server, skip that.

Including Graphics

The Django documentation explains how your website can serve up media (graphics, sounds, etc) in this document (it also shows how the server can list directories). The basic idea is to have a directory for your media. Suppose you have the project created in Django Tutorial 1, which is a directory called gtd.

Execute the command

  > mkdir media

Then, as an example, put a file "fun.gif" (a graphics file) into the media subdirectory. As usual, you need to connect the media directory to a URL, which means putting a regular expression in urls.py:

  (r'^site_media/(?P<path>.*)$', \
  'django.views.static.serve', \
  {'document_root': 'media'}),

The regular expression associates any URL starting with "site_media/" to the media subdirectory of gtd. Now suppose we change the template for status_report.html (located in the templates directory) to display fun.gif. Here is an example:

     <p><img src="../site_media/fun.gif"><p>

The reason for ".." is that the status report view is associated with the "report/" URL, so the ".." steps up one level, to the gtd directory, and then the server finds fun.gif via the urls.py pattern matching mechanism.

Other Topics

I'll wait for student requests on other topics to put here. You can try inherited templates, css, even putting complicated javascript into your template (eventually, even AJAX is possible, but then we'd probably be advised to install Python's JSON package, and there isn't time enough to do this). In a previous semester students used the Google Map API, which basically works by putting some special javascript into the template, and modifying parameters in the javascript as part of your views.py methods.

Personal tools