TALUG Meeting Notes =================== // :Author: Andrew Grieser // :Email: agrieser@gmail.com :Date: June 21, 2008 // :Revision: 1.0 :Key words: django, web design, web framework link:/events/20080621/django.pdf[Django]: Presented by Sam Stuck ---------------------------------------------------------------- Sam Stuck is an independant IT consultant who occasionally finds the time to program websites. His official presentation can be found link:/events/20080621/django.pdf[here]. Sam split the meeting into two sections, the presentation section and the demonstration section. Below are some brief notes from the meeting. Overview ~~~~~~~~ link:http://www.djangoproject.com/[Django] is a web framework for constructing dynamic websites. Hint: the ``D'' is silent. Back in the day, most websites were served with static HTML that had to be manually updated with each change. Today, most websites are dynamic and/or database driven, which automatically updates the content of the site and makes for easier site maintenance. Django uses a three part ``Model View Controller'' scheme to generate web pages. - Model - Abstract group of fields describing the data you are dealing with, presented it in a way that makes logical sense. - View - Which information you want to present from the model. The template is how you present the data. - Controller - Responsible for defining the URLs, extracting variables, and telling the program what it wants. Because Django is written in Python, it can run anywhere Python can, including Linux, Windows, and even the iPhone. Django has about five years of development, so it is quite stable. Additionally, Django has a active development community, and will often help trouble-shoot code if you get stuck (provided you've read the documentation). Django is scalable, it is reported to handle the ``slashdot effect'' quite well. The current Django release is .96, which is getting a little dated. The SVN trunk is quite stable, and is the preferred ``release''. Django will be going 1.0 in September 2008. Django was originally developed for a news website as a way to get sites built on a deadline. Django is licensed with the link:http://www.opensource.org/licenses/bsd-license.php[BSD license]. The name Django comes from link:http://en.wikipedia.org/wiki/Django_Reinhardt[Django Reinhardt] a French gypsy jazz guitarist from the 1940's and 50's. Examples ~~~~~~~~ Sam mentioned several websites that used Django. - link:http://projects.washingtonpost.com/fallen/[Faces of the Fallen (Washington Post)] - link:http://projects.washingtonpost.com/congress/[US Congress Votes Database (Washington Post)] - link:http://www.everyblock.com/[EveryBlock - Aggregated Statistics for Your Block] - link:http://www.djangosites.org/[More Examples] Code ~~~~ Sam then went on to outline how the code works. For more details, see Sam's presentation. - Project - The website - Application - A part of the website Django automatically uses validation to help filter out SQL injection. The template system defaults to escaping all variables in a template, minimizing the risk of cross site scripting. Serving Django ~~~~~~~~~~~~~~ Serving Django is pretty straight forward, just install `Apache2` and `mod_python`. Then add an entry into `httpd.conf` to include project settings into Python path. This will serve the project through Apache. You can also define a media path for serving images and CSS for the templates. ---------------------------------------- vim httpd.conf ---------------------------------------- ---------------------------------------- SetHandler python-program PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE talug.settings # PythonDebug On PythonDebug Off PythonPath "['/home/grey/Web'] + sys.path" SetHandler None ---------------------------------------- Resources ~~~~~~~~~ - link:http://djangoproject.com[djangoproject.com] - link:http://www.djangoproject.com/documentation/[Django Documentation] - link:http://djangobook.com[DjangoBook.com (online book for free)] - IRC `irc.freenode.net #django` - link:http://blog.michaeltrier.com/netcasts[This week in Django podcast] - link:http://pinax.hotcluboffrance.com[Reusable Django applications, wiki, blog etc.] - link:http://www.djangosnippets.org/[Snippets of reusable code] Demonstration ~~~~~~~~~~~~~ Below are some brief notes and screenshots of the demonstration. The demo was to build a blog from scratch in Django. The end result can be downloaded link:/events/20080621/talug.tar.gz[here]. For the installation, we followed the link:http://www.djangoproject.com/documentation/install/[official Django documentation]. The first step was to use subversion to check out the Django Newforms Admin branch. ---------------------------------------- svn co http://code.djangoproject.com/svn/django/branches/newforms-admin/ django-nfa ---------------------------------------- Then we created symbolic links for Django. ---------------------------------------- ln -s `pwd`/django-nfa/django SITE-PACKAGES-DIR/django ln -s `pwd`/django-nfa/django/bin/django-admin.py /usr/local/bin ---------------------------------------- Then we had to start a project. ---------------------------------------- django-admin.py startproject talug ---------------------------------------- This creates a folder with the name of your project and associated Python files/scripts and settings/URLs for the project. Next we created an application. ---------------------------------------- django-admin.py startapp blog ---------------------------------------- Then we configured the settings. ---------------------------------------- vim settings.py ---------------------------------------- After we were done editing, the file looked like this: ---------------------------------------- # Django settings for talug project. #DEBUG = True DEBUG = False TEMPLATE_DEBUG = DEBUG ADMINS = ( # ('Your Name', 'your_email@domain.com'), ) MANAGERS = ADMINS DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. DATABASE_NAME = '/home/grey/Web/talug/db/talug.db' # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = 'America/New_York' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-us' SITE_ID = 1 # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # Absolute path to the directory that holds media. # Example: "/home/media/media.lawrence.com/" MEDIA_ROOT = '' # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash if there is a path component (optional in other cases). # Examples: "http://media.lawrence.com", "http://example.com/media/" MEDIA_URL = '' # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a # trailing slash. # Examples: "http://foo.com/media/", "/media/". ADMIN_MEDIA_PREFIX = '/admin/media/' # Make this unique, and don't share it with anybody. SECRET_KEY = '7cwwg+u0oe=^pvq=hz*t6jc_wp#g24*l+r+lw&=x4r7=7(39fs' # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.load_template_source', 'django.template.loaders.app_directories.load_template_source', # 'django.template.loaders.eggs.load_template_source', ) MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.doc.XViewMiddleware', ) ROOT_URLCONF = 'talug.urls' TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. '/home/grey/Web/talug/templates', ) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'talug.blog', ) ---------------------------------------- Some comments that were made: - DEBUG - Helps troubleshoot errors, but not a good idea for public websites. - ADMINS - The people/emails listed here will get an email if something goes wrong. - INSTALLED_APPS - Only run the listed applications for this site. - SQLite comes with a recent Python installation, so you can use the built in database. NOTE: When using a SQLite database with Apache, the folder containing the file and the file itself should be read-writeable by the webserver user. Next we configured how Django handles URLs. ---------------------------------------- vim urls.py ---------------------------------------- And we just need to uncomment a few lines: ---------------------------------------- from django.conf.urls.defaults import * # Uncomment this for admin: from django.contrib import admin urlpatterns = patterns('', # Example: (r'^blog/', include('talug.blog.urls')), # Uncomment this for admin docs: #(r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment this for admin: ('^admin/(.*)', admin.site.root), ) ---------------------------------------- Then we set up the blog: ---------------------------------------- cd blog vim models.py ---------------------------------------- Where we created two Models: BlogPost and Tag. ---------------------------------------- from django.db import models from django.contrib import admin from django.db.models import permalink # Create your models here. class Tag(models.Model): name = models.CharField(max_length=50) def __unicode__(self): return self.name class BlogPost(models.Model): title = models.CharField(max_length=50) content = models.TextField() tag = models.ManyToManyField(Tag) def __unicode__(self): return self.title def get_absolute_url(self): return '%s/' % self.id class TagAdmin(admin.ModelAdmin): pass class BlogPostAdmin(admin.ModelAdmin): pass admin.site.register(Tag, TagAdmin) admin.site.register(BlogPost, BlogPostAdmin) ---------------------------------------- Next we initiated the database. ---------------------------------------- cd .. mkdir db ./manage.py syncdb ---------------------------------------- When you create a database for the first time, it asks if you want to define a superuser. To explore our database, we installed `sqlitebrowser`. ---------------------------------------- sudo apt-get install sqlitebrowser sqlitebrowser db/talug.db ---------------------------------------- To test the Object-Relational Mapping with the database API, we started the Django Python interactive shell. ---------------------------------------- ./manage.py shell ---------------------------------------- After a bit more work, when we were ready to start testing, we just needed to serve it. Django makes it easy with a built in webserver designed for testing. This works better than Apache because things are updated in real time. ---------------------------------------- ./manage.py runserver ---------------------------------------- When we first started it, we got an error because no templates were defined. This provided an example of the debug output (see the picture below). Below are a series of screenshots of the development. If you want more info, check out the link:/events/20080621/talug.tar.gz[archive of the files]. Debug Info ^^^^^^^^^^ image:screenshot/Screenshot.png["Debug Info",border=3] Admin Interface ^^^^^^^^^^^^^^^ image:screenshot/Screenshot-1.png[Admin Interface] Blog Interface ^^^^^^^^^^^^^^ image:screenshot/Screenshot-2.png[Blog Interface] Simple Template ^^^^^^^^^^^^^^^ image:screenshot/Screenshot-3.png[Simple Template] Edited Template ^^^^^^^^^^^^^^^ image:screenshot/Screenshot-6.png[Edited Template] Links Added ^^^^^^^^^^^ image:screenshot/Screenshot-7.png[Links Added] More Blog Entries Show Up ^^^^^^^^^^^^^^^^^^^^^^^^^ image:screenshot/Screenshot-8.png[Blogs] Clicking On Blogs From Main Page ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ image:screenshot/Screenshot-9.png[Blogs] Clicking On Blogs From Main Page ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ image:screenshot/Screenshot-10.png[Blogs] Next Meeting Topics ------------------- Based on typical summer attendances, and our lack of a speaker for next month, we are going to be taking July off. We will be picking things back up in August once school starts again. Have a good summer! // vim: set syntax=asciidoc: