Category Archives: Tutorials

Php , Jquery, Html and Css tutorials

Install Django and Build Your First App

In our Introduction to Django, we covered all the basics of using the open source web-building framework. If you haven’t read through our beginner’s tutorial, go ahead and do so now. If you’ve already made it through the easy stuff, you’re probably ready to dive into some code and start building — so let’s do it.

Our first step is to grab a copy of Django and set up a development environment where we can tinker away.

Contents

  1. Install Django
  2. Set up your first project
  3. Fill out the project settings
  4. Set up a user
  5. Start the server
  6. Build the blog
  7. Check your head
  8. Tweak the links and tags
  9. Onward and upward

 

Install Django

Django 1.1 was released on July 29th, 2009. You can download the official release here and follow these instructions for installing.

Alternatively, if you want to get the latest and greatest Django tools, you can checkout a copy of the trunk build using Subversion.

If you don’t have Subversion installed, go grab a copy.

Then fire up your terminal and paste in this line:

1 svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk

Once all the files finish downloading, we need to make sure our local Python installation is aware that Django exists on our machine. There are a couple ways to go about that, but a symbolic link to your Python site packages directory is probably the easiest.

Assuming you’re on a *nix system, this line will do the trick:

1 ln -s `pwd`/django-trunk/django /path/to/python_site_packages/django

If you don’t know where your Python site directory is, here’s a handy bit of Python that will tell you:

1 python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

If you’re on Windows, the easiest thing to do is add Django to your PythonPath environment variable. On Windows, you can define environment variables in the Control Panel. To do this, see Microsoft’s Command Line Reference for more details.

The excellent and well-written Django installation docs suggest creating a symbolic link to the file django-trunk/django/bin/django-admin.py in a directory on your system path, such as /usr/local/bin. I find that I don’t use django-admin.py all that often, but you can create the link if you like.

Just paste this code in your shell:

1 ln -s `pwd`/path/to/django-trunk/django/bin/django-admin.py /usr/local/bin

Now that Django is installed and Python knows where it lives, we’re ready to get started.

Remember that you have a Subversion checkout now. If you ever want to update to the latest release, just head to the “django-trunk” folder and run svn update.

 

Set up your first project

OK, let’s get started. From the command line, switch to your web development directory. Something like this:

1 cd ~/sites/dev

Now we’re going to run the django-admin tool we mentioned earlier. If you created the symlink, you don’t need the full path, but if you didn’t here’s the code:

1 python /path/to/django-trunk/django/bin/django-admin.py startproject djangoblog

Yep, you read that last bit correctly — we’re going to build a blog.

Now cd over to the new folder:

1 cd ~/sites/dev/djangoblog

This is going to be our project folder into which we will add various apps. Some we’ll create and some we’ll be downloading as projects from Google Code. I like to keep my Python import statements clean and free of project-specific module names, so I always make sure my root project folder (in this case, djangoblog) is on my Python path. To do that, just add the path to your PythonPath variable.

That way we can write statements like:

1 import myapp

rather than

1 import myproject.myapp

It’s not a huge thing, but it does make your code more portable.

 

Fill out the project settings

OK, we’re getting there. The next step is to fill out our project settings file. Fire up your favorite text editor and open up the settings.py file inside the “djangoblog” directory.

The core of what we need to set up is at the top of the file. Look for these lines:

01 DATABASE_ENGINE = 'sqlite3'  # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
02
03 DATABASE_NAME = '/path/to/djangoblog/djangoblog.db' # Or path to database file if using sqlite3.
04
05 DATABASE_USER = ''             # Not used with sqlite3.
06
07 DATABASE_PASSWORD = ''         # Not used with sqlite3.
08
09 DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
10
11 DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.

Note that we’re using SQLite as a database for development purposes. Assuming you have Python 2.5 installed, you don’t need to do anything to use SQLite. If you’re on either Python 2.3 or Python 2.4, you’ll need pysqlite — make sure you install version 2.0.3 or higher. If you have MySQL or PostgreSQL already installed, feel free to use them.

Make Sure to include the entire pathname, as Django cannot understand ~/ or $HOME in defining the database ie /Users/usrname/Sites/dev/djangoblog/djangoblog.db

The other settings are well documented in the settings.py file and we can skip over most of them for now. But there are a couple of settings we should take care of before moving on. If you look at the bottom of the settings.py file you’ll notice this bit of code:

01 INSTALLED_APPS = (
02
03     'django.contrib.auth',
04
05     'django.contrib.contenttypes',
06
07     'django.contrib.sessions',
08
09     'django.contrib.sites',
10
11 )

This where we tell our Django project which apps we want to install. In a minute, we’ll add our blog app. But for now let’s just add Django’s built-in admin tool. Paste in this line just below the sites app:

1 'django.contrib.admin',

One more thing before we finish with settings.py, here’s a handy trick for the template directories. I generally keep all my templates in a folder named “templates” within my project folder (in this case, “djangoblog”). But I generally move between development and live servers quite a bit and I hate having to change the path to the templates folder. This trick takes care of that:

1 import os.path
2
3 TEMPLATE_DIRS = (
4
5     os.path.join(os.path.dirname(__file__), 'templates'),
6
7 )

Instead of hard coding the path to our templates folder this is dynamic — and it showcases how easy it is to tweak Django using Python. We just import the os.path Python module and then find the path to the directory where settings.py is and then appends ‘templates’ to that path.

Now when we push the site live, there’s no need to change the settings.py file. (Actually you’d probably want to switch to a more robust database, but we’ll get to that much later).

For now, let’s use one of the tools included in manage.py, the syncdb tool. Paste this line in your terminal:

1 python manage.py syncdb

The syncdb tool tells Django to translate all our installed apps’ models.py files into actual database table. In this case the only thing we have installed are some of the built-in Django tools, but fear not, we’ll get to writing our own models in just a minute.

 

Set up a user

Once you enter the syncdb line above, you’ll get some feedback from Django telling you you’ve just installed the auth system. It will walk you through setting up a user. The output looks like this:

01 sng: /djangoblog/ $ python manage.py syncdb
02
03 Creating table auth_message
04
05 Creating table auth_group
06
07 Creating table auth_user
08
09 Creating table auth_permission
10
11 Creating table django_content_type
12
13 Creating table django_session
14
15 Creating table django_site
16
17 Creating table django_admin_log
18
19
20
21 You just installed Django's auth system, which means you don't have any superusers defined.
22
23 Would you like to create one now? (yes/no): yes
24
25 Username (Leave blank to use 'luxagraf'):
26
27 E-mail address: none@none.com
28
29 Password:
30
31 Password (again):
32
33 Superuser created successfully.
34
35 Installing index for auth.Message model
36
37 Installing index for auth.Permission model
38
39 Installing index for admin.LogEntry model
40
41 sng: /djangoblog/ $

Once you’ve created your username and password, it’s time to fire up Django’s built-in server.

 

Start the server

At the command prompt, tell Django to start the server:

01 /djangoblog/ $ python manage.py runserver
02
03 Validating models...
04
05 0 errors found
06
07
08
09 Django version 0.97-pre-SVN-6920, using settings 'djangoblog.settings'
10
11 Development server is running at http://127.0.0.1:8000/
12
13 Quit the server with CONTROL-C.

Now open up your browser and head to http://127.0.0.1:8000/. You should see a page like this:

Image:Djangopart2_1.jpg

It works! But that isn’t very exciting yet, so let’s check out the admin interface. However, before we do that, we need to tell Django what the admin URL is.

Fire up your text editor and open the file urls.py in your “djangoblog” folder. Copy and paste the code below, replacing what’s already in the file:

01 from django.conf.urls.defaults import *
02
03 from django.contrib import admin
04
05
06
07 # Uncomment the next two lines to enable the admin:
08
09 # from django.contrib import admin
10
11 admin.autodiscover()
12
13
14
15 urlpatterns = patterns('',
16
17      (r'^admin/(.*)', admin.site.root),
18
19 )

Now head to http://127.0.0.1:8000/admin/. Log in with the user/pass combo you created earlier and you should see something like this:

Image:Djangopart2_2.jpg

Now that’s pretty cool. If you’ve ever labored over creating an admin system in Ruby on Rails or PHP, you’re going to love Django’s built-in admin system.

But at the moment there isn’t much to see in the admin system, so let’s get started building our blog.

 

Build the blog

Now we could just throw in some code that creates a date field, title, entry and other basics, but that wouldn’t be a very complete blog would it? What about tags? An RSS feed? A sitemap? Maybe someMarkdown support for easier publishing?

Yeah, let’s add all that. But remember Django’s DRY principles — surely, somebody else has already created a Feed app? A Sitemap app?

As a matter of fact Django ships with those built-in.

Nice. But what about tags? Well there’s one of those apps available as well — the cleverly named django-tagging.

Now, there have been some backwards-incompatible changes to Django recently, and as of this writing, django-tagging hasn’t caught up to those yet. So we’re actually going to need to checkout the Newforms Admin branch of the django-tagging codebase.

To do that we’ll grab the files using Subversion. Paste this code into your terminal window:

1 svn checkout http://django-tagging.googlecode.com/svn/branches/newforms-admin django-tagging

Now cd into the new django-tagging folder and type:

1 python setup.py install

Then just drop the tagging folder, which you’ll find inside django-tagging, in your “djangoblog” folder or wherever you’d like to keep it (I use a “lib” folder to hold all my frequently used components, like django-tagging).

There’s also a handy Python implementation of Markdown, so grab that as well (follow the setup instructions on the site to get Markdown installed). Markdown is entirely optional, so feel free to skip it if it’s not your thing.

Got all that stuff stashed in your “djangoblog” folder? Good.

Now let’s go ahead and create our first Django application.

To do that we’ll use Django’s app creating script, which lives inside manage.py in our project folder. Paste this line into your shell:

1 python manage.py startapp blog

If you look inside “djangoblog” you should now see a new “blog” folder. Open that up and find themodels.py file. Open models.py in your favorite text editor and paste in this code:

01 from django.db import models
02
03 from django.contrib.syndication.feeds import Feed
04
05 from django.contrib.sitemaps import Sitemap
06
07
08
09 import markdown
10
11 from tagging.fields import TagField
12
13 from tagging.models import Tag
14
15
16
17 # Create your models here.
18
19
20
21 class Entry(models.Model):
22
23     title = models.CharField(max_length=200)
24
25     slug = models.SlugField(
26
27         unique_for_date='pub_date',
28
29         help_text='Automatically built from the title.'
30
31     )
32
33     body_html = models.TextField(blank=True)
34
35     body_markdown = models.TextField() #note, if you're using Markdown, include this field, otherwise just go with body_html
36
37     pub_date = models.DateTimeField('Date published')
38
39     tags = TagField()
40
41     enable_comments = models.BooleanField(default=True)
42
43     PUB_STATUS = (
44
45         (0, 'Draft'),
46
47         (1, 'Published'),
48
49     )
50
51     status = models.IntegerField(choices=PUB_STATUS, default=0)
52
53
54
55     class Meta:
56
57         ordering = ('-pub_date',)
58
59         get_latest_by = 'pub_date'
60
61         verbose_name_plural = 'entries'
62
63
64
65     def __unicode__(self):
66
67         return u'%s' %(self.title)
68
69
70
71     def get_absolute_url(self):
72
73         return "/%s/%s/" %(self.pub_date.strftime("%Y/%b/%d").lower(), self.slug)
74
75
76
77     def save(self):
78
79          self.body_html = markdown.markdown(self.body_markdown, safe_mode = False)
80
81          super(Entry, self).save()

Let’s step through the code line by line and we’ll talk about what’s going on.

First we import the basic stuff from django, including the model class, the Feed class and the Sitemap class.

Then we import the tagging and markdown files we just saved in our project folder.

Once we have all the modules we’re going to use, we can create our blog model. I elected to call it Entry — you can change that name if you like, but remember to substitute your name everywhere I refer to Entry.

Entry extends Django’s built-in model.Model class, which handles all the basic create read update and delete (CRUD) tasks. In other words, all we have to do is tell Django about the various elements of the database table (like the title field, the entry slug, et cetera) and all the hard work is handled behind the scenes.

The first bit of our Entry class definition just defines all our various blog entry components. Django will use this information to create our database tables and structure, and also to generate the Admin interface.

Note that we’re using Django’s various model fields. Most of it should be self-explanatory, but if you want to learn more about each type, check out the Django documentation. Also be aware that there are quite a few more field types available. This is only one example.

One thing worth mentioning is the body_html = models.TextField(blank=True) line. What’s up with that blank=True bit? Well that information is part of Django’s built-in Admin error checking.

Unless you tell it otherwise, all fields in your model will create NOT NULL columns in your database. To allow for null columns, we would just add null=True. But adding null=True only affects the database, Django’s Admin system would still complain that it needs the information. To get around that, we simply add the blank=True.

In this case, what we’re going to do is fill in the body_html field programatically — after we hit save in the Admin and before Django actually writes to the database. So, we need the Admin section to allowbody_html to be blank, but not null.

Also worth mentioning is the Meta class. Meta handles things like how Django should order our entries and what the name of the class would be. By default, Django would refer to our class as “Entrys.” That offends my grammatical senses, so we’ll just explicitly tell Django the proper plural name of “entries.”

Next, we have a few function definitions. All Python objects should return their name. Django recently added unicode support, so we’ll return our name in unicode. Then there’s get_absolute_url. As you might imagine this refers to the entry’s permalink page.

When we get to creating templates, we’ll use this to put in our permalinks. That way if you ever decide to change your permalinks you only have to change one line and your entire site will update accordingly — very slick.

The last function simply overrides Django’s save function. Every Django model has a save function, and since we didn’t expose the body_html field, we need to fill it in. So we grab the text from ourbody_markdown field (which is exposed in the admin), run it through the markdown filter and store it inbody_html.

By doing it this way, we can just call this field in our templates and we’ll get nicely formatted HTML as output, yet the process stays transparent — write in markdown, display HTML.

If you’re not using Markdown, just delete the save function, there’s no need to override it if you aren’t using the Markdown module.

 

Check your head

Now we need to tell Django about our new apps. Open up settings.py again and add these lines to your list of installed apps:

01 INSTALLED_APPS = (
02
03     'django.contrib.auth',
04
05     'django.contrib.contenttypes',
06
07     'django.contrib.sessions',
08
09     'django.contrib.sites',
10
11     'django.contrib.admin',
12
13     'djangoblog.tagging',
14
15     'djangoblog.blog',
16
17 )

Once that’s done, head over to the terminal and run manage.py syncdb. Refresh your admin section and you should see the tagging application we downloaded. Super cool.

But where’s our blog model? Well, even though Django knows about our blog app, we haven’t told the app what to do in the Admin section.

So head back over to your text editor and create a new file. Name it admin.py and save it inside the “blog” folder. Now add these lines:

01 from django.contrib import admin
02
03
04
05 from djangoblog.blog.models import Entry
06
07
08
09 class EntryAdmin(admin.ModelAdmin):
10
11     list_display = ('title', 'pub_date','enable_comments', 'status')
12
13     search_fields = ['title', 'body_markdown']
14
15     list_filter = ('pub_date', 'enable_comments', 'status')
16
17     prepopulated_fields = {"slug" : ('title',)}
18
19     fieldsets = (
20
21         (None, {'fields': (('title', 'status'), 'body_markdown', ('pub_date','enable_comments'), 'tags', 'slug')}),
22
23     )
24
25
26
27 admin.site.register(Entry, EntryAdmin)

OK, what does all that do?

The first thing we do is import Django’s admin class, as you might suspect, admin controls how the admin interface looks. Now, these customizations are entirely optional. You could simply write pass and go with the default admin layout. However I’ve customized a few things and added some filters to the admin list view so we can sort and filter our entries. Note that if you aren’t using Markdown, just replacebody_markdown with body_html.

We’ve also used a handy tool, Django’s prepopulated_fields, which will use a bit of Javascript to automatically build a slug from our title.

The last step is to register our admin customizations with Django’s admin app. If you aren’t actually making any customizations, you could just write the model name. In other words the admin class name is optional.

If you refresh your admin page you should now see the blog model with a link to create and edit blog entries.

Want more control over what shows up in your admin? For instance, if it’s a personal site, you probably don’t need the “Users” section in the admin. Let’s customize what shows up. To do that we’re going to create a new file, again named admin.py, but put this one at the project level, inside the djangoblog folder.

Okay now paste in this code:

01 from django.contrib import admin
02
03 from djangoblog.blog.models import Entry
04
05 from djangoblog.blog.admin import EntryAdmin
06
07
08
09 class AdminSite(admin.AdminSite):
10
11     pass
12
13
14
15
16
17
18
19 site = AdminSite()
20
21 site.register(Entry, EntryAdmin)

All this does is override Django’s default AdminSite and then simply registers our Entry model and admin classes. Of course you could do more than simply pass, check the Django docs for customization tips.

Now if you go back and refresh the admin page you should see just the things we’ve built — the Entries and Tags models.

 

Tweak the links and tags

One last thing, let’s jump back over to our models.py file; we’re going to add one extra function to our blog to improve its usability. Add these lines to the bottom of your models.py file:

01 def get_previous_published(self):
02
03     return self.get_previous_by_pub_date(status__exact=1)
04
05
06
07 def get_next_published(self):
08
09     return self.get_next_by_pub_date(status__exact=1)
10
11
12
13 def get_tags(self):
14
15     return Tag.objects.get_for_object(self)

So what’s going on here?

Django includes a bunch of built-in methods for common tasks, like displaying next and previous links on pages. The function is called get_previous_by_ with the last bit of the function being the name of your datetime field, in our case pub_date. However, we included the ability to save drafts in our model, and, unfortunately, Django’s built-in function doesn’t know about our drafts. So, it will automatically include them in our next/previous links. This obviously isn’t what we want.

So what we’ve done is wrap the Django function with a one-liner:

1 def get_previous_published(self):
2
3     return self.get_previous_by_pub_date(status__exact=1)

All this does is wrap the Django function with a new name get_next_published, call the originalget_previous_by_ function, but add a filter so that only published entries are included in the results.

The last function in that set, get_tags, is just a time saver. There’s a good chance you’ll want to list all the tags you’ve added to your entry, so I’ve included a convenience method that does just that.

 

Onward and upward

Whew! That’s a lot of code to sort through, and we’ve glossed over a few things. But when you look at themodels.py file and consider that from these 49 lines of code, Django was able to generate an entire blog website, it doesn’t seem like so much code at all, does it?

Save the file and head back over to your browser. Refresh the admin page and click “Add new.” Feel free to create a few entries — blog monkey blog!

So now we’ve got our back-end blogging system set up and everything in in place to create a public site. Feel free to take a well deserved break.

The next thing to do is dress up the public-facing side of our blog, which is functional, yet totally vanilla. We tackle that in Lesson 3: Use URL Patterns and Views in Django, so click ahead once you feel ready.

In the meantime, you’ve learned enough about Django to continue building the backend, and you can always consult the Django Book if you want to strike out on your own.

Use URL Patterns and Views in Django

Last time around, we installed Django and started building a blog application. We got Django’s built-in admin system up and running and explored some third-party libraries like the django-tagging project.

So far we have some cool administrative tools, but no website for the rest of the world to see. This time around, we’ll work on displaying our content to the world by building the URL patterns and constructing some “views” — a term with a very specific meaning within the Django framework.

Everything we’re going to do will make more sense if you understand how Django processes your visitor’s request. We went over some of this in our introduction, but here’s a quick refresher course.

Contents

  1. How content is presented
  2. Working with urls.py
  3. Thoughts on URLs
  4. Being Generic is Good
  5. Go your own way
  6. Conclusion

 

How content is presented

The Django flow goes something like this:

1) Visitor’s browser asks for a URL.
2) Django matches the request against its urls.py files.
3) If a match is found, Django moves on to the view that’s associated with the URL. Views are generally found inside each app in the views.py file.
4) The view generally handles all the database manipulation. It grabs data and passes it on.
5) A template (specified in the view) then displays that data.

Designer and coder Jeff Croft has put together a visual representation of this flow that makes it even easier to understand:

See the full size original (along with explanatory text) atFlickr.

With that in mind, let’s start building our public site by creating some URL patterns.

 

Working with urls.py

Remember the urls.py file where we set up our admin URLs in the last lesson? Open that file in your favorite text editor.

Now, we could define all our URLs in this file. But then what happens if we want to reuse this blog in an entirely separate project? We’d get a mess.

A far better approach is to define all your app-specific URLs in a file that lives inside the app itself. In this case, we’re going to use a file inside the blog app, which will also be named urls.py.

However, before we start with that file, we need to tell Django about it. So add this line to the project-wideurls.py file, just below the line that defines the admin URLs, like so:

01 from django.conf.urls.defaults import *
02
03 from django.contrib import admin
04
05
06
07 urlpatterns = patterns('',
08
09     (r'^admin/(.*)', admin.site.root),
10
11     (r'^blog/', include('djangoblog.blog.urls')),
12
13 )

OK, now head into the blog app folder and create a new urls.py file, which we’ll use to hold all the URLs related to our blog application.

 

Thoughts on URLs

One of the nice things about Django is that it forces you to think about your URL designs, something many people don’t spend much time considering. If, perchance, you’ve never spent too much time thinking about URLs, now is good time to read the W3C guide on the subject.

As the W3C points out, good URLs never change. In fact, even bad URLs never change — people change them. But when you change your URLs, you break everyone’s bookmarks and inbound links. So, spend a bit of time designing a good URL scheme from the beginning and you shouldn’t need to change things down the road.

I would actually add one item to the W3Cs guidelines: good URLs are hackable. What do I mean by hackable? Let’s say our blog has URLs like:

1 http://mysite.com/blog/2008/jul/08/post-slug/

That URL would display the blog post with the slug named “post-slug” which was published on July 8, 2008.

Note: “Slug” is an old newspaper term. An article about fires in Nevada would probably be slugged “nv-fires” for easy identification. In this context, the slug refers to the last bit of the URL and can contain letters and dashes rather than spaces.

Ideally, if the user heads up to their browser’s location bar and chops off the post-slug/ bit, they would see all the blog entries from July 8, 2008. If they were to chop off 08/, they would see all the posts from July 2008, and so on.

In other words, the URL is hackable. Now, most people probably won’t do that. But in addition to making your site easier to navigate for the hands-on types, this rule also enforces an easy-to-use structure around which to build your site. In this case, the date-based structure was probably already obvious. But what about tags?

1 http://mysite.com/blog/tags/tag-slug/

This URL structure uses the same idea, but one-ups it. Not only can you hack the URL to get to a list of all tags (provided you create such a page), it should be obvious that you could plug just about any word into the “tag-slug” part of the URL and it effectively functions like a tag-based search engine.

So, how do we actually build the URLs?

 

Being Generic is Good

Let’s get started. Paste this code into your blog/urls.py file:

01 from django.conf.urls.defaults import *
02
03 from djangoblog.blog.models import Entry
04
05 from tagging.views import tagged_object_list
06
07
08
09 info_dict = {
10
11     'queryset': Entry.objects.filter(status=1),
12
13     'date_field': 'pub_date',
14
15 }
16
17
18
19 urlpatterns = patterns('django.views.generic.date_based',
20
21     (r'(?P<year>d{4})/(?P<month>[a-z]{3})/(?P<day>w{1,2})/(?P<slug>[-w]+)/$','object_detail', dict(info_dict, slug_field='slug',template_name='blog/detail.html')),
22
23     (r'^(?P<year>d{4})/(?P<month>[a-z]{3})/(?P<day>w{1,2})/(?P<slug>[-w]+)/$','object_detail', dict(info_dict, template_name='blog/list.html')),
24
25     (r'^(?P<year>d{4})/(?P<month>[a-z]{3})/(?P<day>w{1,2})/$','archive_day',dict(info_dict,template_name='blog/list.html')),
26
27     (r'^(?P<year>d{4})/(?P<month>[a-z]{3})/$','archive_month', dict(info_dict, template_name='blog/list.html')),
28
29     (r'^(?P<year>d{4})/$','archive_year', dict(info_dict, template_name='blog/list.html')),
30
31     (r'^$','archive_index', dict(info_dict, template_name='blog/list.html')),
32
33 )

Now, remember when I said that the URL patterns determine which view Django will use to grab data from our database? In that scheme, we would write our regular expressions and then point each pattern to a function in views.py.

But we’re cheating a little bit here by taking advantage of some built in views that Django provides. These are known as “generic views.”

Django’s developers wisely figured that date-based archives were likely to be a common problem that just about every site has at least some use for, so they baked in some generic data-based views.

What we’ve done here is take advantage of the built in views to construct our URLs.

Let’s start with info_dict, which is just a Python dictionary that holds two things: a queryset containing all of our public blog entries and the name of our date field in the database.

It’s important to realize that Django querysets are lazy — Django only hits the database when the queryset is evaluated, so there’s no performance penalty for defining a queryset that looks for everything, then filtering it on a case-by-case basis. This happens to be essentially what we’ve just done.

Passing the queryset to the generic view enables Django to automatically do whatever date sorting we need, for instance, to show all the entries from a single month or year. For more info on querysets, check out the database API docs on the Django site.

That’s all the URL patterns list is: a regular expression that looks at the URL and figures out what view to use. The view then determines which entry or list of entries to show.

Let’s break it down and go through each part of the URL pattern. We’ll use the first line as an example:

1 (r'(?P<year>d{4})/(?P<month>[a-z]{3})/(?P<day>w{1,2})/(?P<slug>[-w]+)/$','object_detail', dict(info_dict, slug_field='slug',template_name='blog/detail.html')),

The first bit:

1 (?P<year>d{4})/(?P<month>[a-z]{3})/(?P<day>w{1,2})/(?P<slug>[-w]+)/$

is the regular expression. In this case, the expression will match our permalink URLs and capture the year, month, day and slug of a particular entry. That information will then be passed to the next bit,object_detail, which is the name of the generic view that will pull out a single entry.

The full path to object_detail is actually django.views.generic.date_based.object_detail, but since we started our urlpattern definition by including the django.views.generic.date_based bit, there’s no need to retype it every time, we just need to call the individual function, in this case object_detail.

After we grab the URL info and pass it to the object_detail function, we also pass along a dictionary of data. Most of the time you can just pass info_dict here. The object_detail generic view is something of an exception because it needs to pass along the slug_field variable as well.

I wanted to show some of the other data you can include as well, so I wrapped it in the dict your see above. In this case, we’ve passed info_dict, the slug_field and the name of the template Django should use to display the data.

The rest of the patterns just work their way back up the URL using ever-shortening regular expressions until we get to nothing, which would be the URL: http:/mysite.com/blog/.

We’ll be using that URL as the location of our archive page. So, I guess you can think of this as a tumblelog rather than a traditional blog, which would probably have separate archive and home pages. Naturally, you can tweak the URL patterns to fit whatever design you’d like.

Django’s generic views are incredibly powerful, and there are quite a few other options beyond just the date-based ones we’ve used here. There’s also a super-handy built-in pagination system for some generic views. Be sure to read through the documentation on the Django website and also have a look at James Bennett’s excellent guide to the various ways you can wrap and extend generic views.

 

Go your own way

Django’s generic views can save you quite a bit of time, but you will probably encounter some situations where they don’t quite do exactly what you want. When that happens, it’s time to write your own views.

Fear not, writing a custom view isn’t hard.

We’ve pretty much covered our blogs URLs, from date-based archives to the detail pages, but what about the pages that display our entries by tag?

The tagging application actually includes some views that we could use. But for the sake of example, we’ll write some custom views. Rather than overwriting what’s already in the tagging application, we’re just going to create a views file that lives on its own in our main project folder.

So, inside the “djangoblog” folder create a new file named tag_views.py. Remember, before we get started there, we need to tell Django about the tag_views file, so open up djangoblog/urls.py and add the last line below what’s already there:

1 urlpatterns = patterns('',
2
3     (r'^admin/(.*)', admin.site.root),
4
5     (r'^blog/', include('djangoblog.blog.urls')),
6
7     (r'^tags/(?P<slug>[a-zA-Z0-9_.-]+)/$', 'djangoblog.tag_views.tag_detail'),
8
9 )

Here, we haven’t included another url.py file like we did with the lines above. You could argue that we should, but just to show that you don’t have to, we’ll just point directly to our tag_views.py file which will soon have a function named tag_detail. Note that in the tag URL, we’re capturing the slug paramater. We’ll use that in just a minute to filter our blog entries by tag.

Now it’s time to create the tag_detail function in the tag_views.py file. Open up that file in your text editor and paste in this code:

01 from django.views.generic.list_detail import object_detail
02
03
04
05 from tagging.models import Tag,TaggedItem
06
07 from blog.models import Entry
08
09
10
11 def tag_detail(request, slug):
12
13     unslug = slug.replace('-', ' ')
14
15     tag = Tag.objects.get(name=unslug)
16
17     qs = TaggedItem.objects.get_by_model(Entry, tag)
18
19     return object_list(request, queryset=qs, extra_context={'tag':slug}, template_name='tags/detail.html')

What’s going on here? Well, ignore the first line for now, we’ll get to that in a minute. We import all the things we need — in this case, the Tag and TaggedItem classes from django tagging and then our own Entry class. Then we define the tag_detail function, which is just an ordinary Python function that takes two parameters. The first is request which Django passes to all view functions, and the second is the slug paramater we defined in our URL pattern above.

Now because we’re using a slug for our tag URLs, but strings of words with spaces for our tags, we need to get rid of the dashes and replace them with spaces (Remember, a slug can contain letters and dashes, but not spaces).

Because our slug parameter is just a string, we can use the normal Python string function to make that replacement.

In the next line, we look up our tag name in the database using the objects manager. Then we take advantage of django-tagging’s built in function get_by_model to grab all the entries with the given tag.

The last step is to return something so that Django can load our template and display the entries to our visitor. To do that we’re going to use another of Django’s generic view functions — object_detail from the generic list views.

Object_detail requires a few things. First is the request object, then the queryset of results. After that, I’ve added an extra context variable named tag, so our template will be aware not just what entries to display, but also the current tag. Finally, the last item simply tells Django which template to use.

We haven’t yet created a URL for http://mysite.com/blog/tags/ to list all our tags, but that’s a good stepping stone to practice writing a view function on your own. Here’s a hint: you can use pretty much the same code we used for the tag_detail function, but you don’t need to worry about the slug param. And instead of looking up TaggedItems, just grab all the tags (i.e. qs = Tag.objects.all())

 

Conclusion

And there you have it, a quick and dirty overview of how URL patterns and view work in Django.

If you point your browser to our development URL (http://127.0.0.1:8000/blog/) you should see a Django error page complaining that the template blog/list.html does not exist. This is true, since we haven’t created it yet (visiting the tag pages will give you “list index out of range” error, also due to the missing templates).

But don’t worry — in the next lesson, we’ll dive into Django’s template system and explore all the cool things we can do, including how to write custom template filters and more.

See you then!

Get Started With Django

Django is a web framework designed to help you build complex web applications simply and quickly. It’s written in the Python programming language.

Django takes it name from the early jazz guitarist Django Reinhardt, a gypsy savant who managed to play dazzling and electrifying runs on his instrument even though two of the fingers on his left hand were paralyzed in an accident when he was young.

Thus, it’s a fitting name for the framework: Django can do some very complex things with less code and a simpler execution than you’d expect. It doesn’t take a heavy hand to build with Django. The framework does the repetitive work for you, allowing you to get a working website up quickly and easily.

Contents

  1. Django’s DRY pledge
  2. Background
  3. Why isn’t Django a 1.0 release?
  4. Structural overview
  5. So how does Django work?
  6. Dive in

 

Django’s DRY pledge

Django was designed from the ground up to handle two common web developer challenges: intensive deadlines and strict adherence to the Don’t Repeat Yourself (DRY) principle. DRY sounds exactly like what it is: Why write the same code over and over again?

The result is a fast framework, nimble and capable of generating full site mockups in a very short time. Django’s slogan captures its essence quite nicely: “The web framework for perfectionists with deadlines.”

But quick doesn’t mean sloppy. Django comes with a slick built-in section for administering sites. The admin section supports a variety of caching options (including Memcached) and a host of other stable, scalable tools.

Perhaps the best part about Django is its outstanding documentation. Unlike many open source projects, Django has very thorough and readable docs available online. If you have any problems with our tutorials, head over to the Django site for additional reading. Also consider joining the django-users Google Groupwhich is full of helpful folks who can point you in the right direction if you run into trouble.

 

Background

Before we dive in, it’s worth pausing for a moment to understand where Django comes from, which has influenced both what it is and what it is not.

Django was developed over a two year period by programmers working for an online news operation, theLawrence Journal-World Online in Lawrence, Kansas. Eventually, the team realized it had a real framework on its hands and released the code to the public under an open-source BSD license.

Once it became a community project, the development took off and Django began to pop up all over the web. For a complete list of Django sites, check out Django Sites. Notable examples include Pownce, The Washington Post and Everyblock.

Perhaps the most common misconception about Django is that it’s a content management system. It’s not. It’s a web framework. It is a tool in which to build a CMS, like Drupal or other systems, but not one in itself.

Django is designed to work in a slightly modified Model-View-Controller (MVC) pattern. MVC is a software engineering architecture concept describing how a program can change the visual aspect and the business aspect without affecting one another. The original Django developers refer to it as a model, template and view (MTV) framework.

However, in Django’s vision of MVC development, the “view” refers to the data presented to user. Mind you, not how data looks, but which data. In other words, to quote the Django documentation, “the view describes which data you see, not how you see it.”

It leaves the “how” to an additional element found in Django: the template.

 

Why isn’t Django a 1.0 release?

It is! Django was released as 1.0 on September 3rd, 2008. Django 1.1 was released on July 29, 2009.

 

Structural overview

Django was designed to make web development fast and easy — dare we say, even fun. And by fast, they mean fast. Once you’re comfortable with Django, it’s not hard to go from a simple wireframe to a working demo site in an hour or so.

For development purposes, Django is entirely self-contained. It includes a command line interface, a web server and everything you need to get up and running without installing anything other than Django.

That said, the web server included with Django is not intended to be used in a production environment. The preferred method is to run Django through mod_python or mod_wsgi. Don’t worry, we’ll get to mod_pythonand mod_wsgi in our more advanced tutorial. First, let’s look at how you might go about building a Django application.

As it turns out, building a Django app actually takes much less time than explaining how to build it.

Before we start building sites, it’s worth asking: What do you mean by building a Django app? Django’s official documentation and many of its built-in tools are set up to create projects, or containers for your whole site. Within projects you have many apps, or sections of your site.

Apps don’t need to be in projects, and in many cases it’s better not to put them there.

For the sake of example, here’s a very high-level overview of how a Django app is built:

First, create a project using the built in command line tool (python django-admin.py startproject projectname). This will generate a new folder containing the project’s base settings file which you can use to specify database connections, template locations and more. Also in the folder is urls.py, which defines your base URLs and manage.py, which contains a standard set of command line tools.

Next, create an app using the built in command line tool python manage.py startapp appname.

Once the app folder is in place, look inside. You’ll see three files: models.py, urls.py and views.py. These are the files you’ll use to actually build the app:

  • models.py to design your model
  • urls.py to write your URLs
  • views.py to create your views

Django includes its own template language, but as with many elements of Django, using it entirely optional. You can drop in another template language if you like, but you might want to give Django’s a try first. It’s simple and fast, and it’s already there.

The other thing to keep in mind is that Django is written in Python and requires Python 2.3 or higher. Mac OS X and most Linux distros ship with Python 2.5, so you shouldn’t have any problems. Windows users, however, may need to install Python separately.

 

So how does Django work?

The simplest way to look at Django is to break it down into its component parts. First off, there’s amodels.py file which defines your data model by extrapolating your single lines of code into full database tables and adding a pre-built (totally optional) administration section to manage content.

The next element is the urls.py file which uses regular expressions to capture URL patterns for processing.

The actual processing happens in your views which, if you haven’t seen the pattern yet, live in views.py. This is really the meat of Django, since views are where you grab the data you’re presenting to the visitor.

Here’s what happens when a visitor lands on your Django page:

1. First, Django consults the various URL patterns you’ve created and uses the information to retrieve a view.

2. The view then processes the request, querying your database if necessary.

3. The view passes the requested information on to your template.

4. The template then renders the data in a layout you’ve created and displays the page.

 

Dive in

Now you have at least some idea of how Django works, you’re ready to dive in and get your hands dirty. It’s really the best way to learn. For the sake of example, we’ll be building a blog-type site. It makes a nice intro to Django and takes advantage of some of Django’s handy shortcuts and other features.

We aren’t going to just build a blog, we’ll also walk through adding a contact form, static pages (like an “about” page) and even integrate it with del.icio.us web services to display all your del.icio.us bookmarks on your new Django blog.

Get Started with Web Frameworks

If you’ve built a few websites from scratch, chances are you’ve noticed that you have to solve some of the same problems over and over again. Doing so is tiresome and violates one of the core tenants of good programming — Don’t Repeat Yourself (DRY).

Luckily for you other people long ago noticed that web developers face similar problems when building a new site. Sure, there are always edge cases which will vary from site to site, but for the most part there are four general tasks we developers have to handle — Create, Read, Update and Delete, otherwise known as CRUD.

To help you out, a number of web application frameworks have emerged over the years. You might have heard of some of the more famous frameworks — Ruby on Rails, CakePHP and Django.

Contents

  1. What is a Web Framework?
  2. What Can You Do With a Web Framework
  3. How Do You Choose A Framework?
  4. Popular Frameworks
  5. Frameworks Tutorials on Webmonkey

 

What is a Web Framework?

A web framework is a software framework designed to simplify your web development life. Frameworks exist to save you from having to re-invent the wheel and help alleviate some of the overhead when you’re building a new site. Typically frameworks provide libraries for accessing a database, managing sessions and cookies, creating templates to display your HTML and in general, promote the reuse of code.

It’s important not to confuse a framework with a content management system. While a framework deals with many of the same issues and, in some cases, may make it very easy to build a content management system, a framework is much more general.

In fact a framework isn’t really anything at all. Think of a framework as a collection of tools, rather than a specific thing.

 

What Can You Do With a Web Framework

Frameworks exist to make building a website faster and easier. Typically frameworks provide tools to cover the common CRUD cases. For instance you’ll likely find libraries for accessing a database, managing sessions and cookies, creating templates to display your HTML pages and more.

Frameworks also promote the reuse of code. With a good framework you only need to design, for instance, a contact form once. Then you can drop your generic contact form code into all your projects and save yourself some time and effort.

Nearly any site you’re going to build will have to interact with a database. Frameworks generally offer some means of doing so without having to delve into writing your own SQL every time you want to create, read, update or delete a record.

Similarly, most frameworks either provide a template system, or make it easy to add on your own templating system so that common chunks of HTML that rarely change, for instance, the header and footer of your page, need only be written once.

 

How Do You Choose A Framework?

Although having a wide range of framework choices is definitely good, it can also be a source of confusion for inexperienced developers. With all of the possibilities out there, choosing one can be a daunting task the newcomer, so how do you decide?

That’s something of a religious question, but a good place to start is to see if your favorite scripting language has a framework available. The Ruby in Ruby on Rails refers to the fact that Rails is a Ruby framework. So if you’re a Ruby fan, Rails might be the framework for you, but there’s also Nitro and Merb.

Python fans have a few to choose from. Django is fast becoming the Python framework of choice, but there are other options like Pylons and TurboGears. PHP lovers can check out CakePHP, Symfony andZend. There are also Perl and Java frameworks for those that enjoy Perl or Java.

However, just because there’s a framework available in your favorite programming language doesn’t mean it’s the ideal choice. Each of the frameworks mentioned has its strengths and weaknesses and you’ll have to evaluate each to see which is the best fit for your site’s needs.

Although none of these should be the sole criteria, each of these frameworks are noted for certain things.

For instance, Ruby on Rails offers tight integration with JavaScript, making it a popular choice for Ajax heavy sites. Ruby on Rails even includes the Prototype Javascript Library which you can integrate directly.

Django was developed for a very large newspaper website and offers a fantastic auto-generated site administration section for your site’s users to create, edit and update content. It also includes built-in tools for caching data and building flexible URLs.

CakePHP borrows many conceptual ideas from Ruby on Rails but applies them to PHP. Given the widespread availability of PHP on shared web hosting servers, and the fact that Cake supports PHP4, it might be the most widely usable framework.

There are literally dozens, if not hundreds, of more web frameworks in all sorts of programming languages, but there just isn’t room to cover them all. Perhaps the best way to choose a framework is to simply dive and and try building a site with each one. That way you can see which frameworks fits the best with your style and goals.

Ruby on Rails for Beginners

If you’re like me, you’re reading this on your bright-red custom-built laptop in a soothing rosemary-scented bubble bath, and you’re wondering, “Why do I want another interpreted programming language? I can find my way around Perl and PHP and maybe a little Python. And Unix shell scripting. I feel fine. Why do people keep talking about Ruby?”

Contents

  1. Why Ruby is Cool
  2. Why Rails Is Cool
  3. Installing Ruby and Rails
  4. Using It
    1. Step one:Set up the database
    2. Step two:Create the scaffolding
    3. Steps three and beyond:Customize the application

 

Why Ruby is Cool

Like so many of the very coolest things, Ruby was invented in Japan in the ’90s. Ruby is purely object-oriented; even things like integers and strings have intrinsic methods and properties. So, for example,print "Webmonkey".reverse outputs “yeknombeW”. It’s a clean, pretty language, with a flexible, predictable syntax that’s easy to read and write, and comfortable for people coming from Perl or C.

It’s more than easy to learn and use though — it’s fun, especially if you use Why’s (Poignant) Guide to Ruby, an engrossing, whimsical adventure story that reads like a collaboration between Stanislaw Lem andEd Lear and just happens to teach the reader Ruby (and the love of Ruby). (Note to editor:can you get this guy to write for Webmonkey?)

 

Why Rails Is Cool

Much of the attention being heaped on Ruby these days is fueled by Rails, a framework for using Ruby to make web applications. Ruby on Rails has been used for a handful of high-profile sites, such as Basecampand Backpack.

Rails is much more than just a tube of glue with which to stick Ruby on the web. And of course, it’s possible to program web apps in Ruby without getting Rails involved — just tell Apache to invoke your Ruby scripts via CGI. Rails is a programming toolbox, with a wealth of pre-written code that implements the structure and many of the common functions of a database-driven site. That eliminates much of the preliminary busywork necessary to create such a site, but also enforces a tight, sane structure on the code, which has the effect of making development very facile. It’s like working in a well-organized company:it takes a little time to figure out who sits where and what they do, but once you understand the structure, you can use it to your advantage without having to make lots of micro-managerial decisions all the time.

Rails uses a model-view-controller style of architecture, in which the database and its representation (“model”), the user interface (“view”), and the functional logic (“controller”) of the application are all kept neatly separate. The advantages of this architecture can be debated, but at least it means you have to try pretty hard if you want to make an application that’s not clean, portable, and sharable.

And easy. All over the web you’ll find testaments to how “The first time I ever looked at Ruby on Rails, I built a mobile-platform, social-networked auction site in six hours with one hand, while making this awesome Ajax-enabled to-do-list manager with the other!”

Regardless of Rails’s actual merits, the enthusiasm — fueled by things like the Rails Day festival, in which hundreds of competing developers had 24 hours to build a web app — is contagious. Let’s join the party!

 

Installing Ruby and Rails

For integration into an existing web setup, Rails can run under Apache via CGI or FastCGI. It also comes conveniently bundled with its own web server software, WEBrick, which is written in Ruby and serves sites on port 3000 by default, making it easy to test RoR apps on a development machine.

Cool people who manage their own web servers can install first Ruby and then Rails (you’ll also need a database, like MySQL or PostgreSQL) and get started — the official installation instructions are more comprehensive, platform by platform, than I could ever hope to be. Rails hasn’t become a popular offering on hosting services the way Perl and PHP are. If you pay for hosting on a shared server, your experience may vary. You can beg the host to install it on the server, or install your own Rails and work around snags you encounter. If you just want a version to play around with on your local Windows machine, Curt Hibbs goes into painstaking detail here. We can just use the built-in web server to start with, and you can configure it to work with your Apache installation later.

 

Using It

However you get your RoR on your system, the procedure is pretty simple once it’s installed. Let’s take a stroll through building a basic application. How about a bookmark manager? We’re only going to walk through the starter steps, so if you want an actual full-featured bookmark manager at the end of the day, I am not your guy. I can only teach you to fish; poaching the result in a nice court-bouillon is up to you.

Grab your stopwatches — let’s see how long it takes to get this site off the ground.

 

Step one:Set up the database

Let’s create the MySQL database that Rails is going to use to store our bookmarks. Rails is particular about certain things. Mainly, it likes the primary key in the database table to be an auto-incremented integer called ‘id’, and the database table to have a plural name (i.e., ending in ‘s’). Ours will be “bookmarks”; woe unto you if you want Rails to organize your gooses. Me, I want the table to store a URL, a name, and a description for each bookmark. So, using my command-line MySQL interface, I create the database:

1 mysql> CREATE DATABASE bookmarker;

and then create and populate the table within it:

1 mysql> USE DATABASE bookmarker;

note: some versions of MySQL don’t require the DATABASE keyword.

01 mysql> CREATE TABLE bookmarks (
02
03
04
05   ->  id SMALLINT (5) NOT NULL auto_increment,
06
07
08
09   ->  url VARCHAR (255),
10
11
12
13   ->  name VARCHAR (100),
14
15
16
17   ->  description VARCHAR (255),
18
19
20
21   ->  PRIMARY KEY (id)
22
23
24
25   -> );

If you have a mouse and like to administer your MySQL in some snazzier way, feel free to use that instead.

 

Step two:Create the scaffolding

Now the magic begins. Regardless of the nature of a Rails app, the first step, once the database is in place, is to create a starter framework. In a nice fresh directory, we type the magic words on the command line:

1 rails Bookmarker

And Rails automatically creates a directory called Bookmarker containing eleven subdirectories which constitute our budding application. Let’s pause here to take a brief look at what goes into a Rails app.

1 $ ls Bookmarker
2
3 CHANGELOG README Rakefile app/ components/ config/ db/ doc/ lib/ log/ public/ script/ test/ vendor/

public is the public face of the application. It’s the only directory of the bunch that the web server has access to. It contains the dispatch scripts, which are the intermediaries between the browser and the application, and the directories where we’ll put images, JavaScript and CSS.

The app directory contains the meat of our application, including some elements you may remember from a few sections ago:

1 ls Bookmarker/app
2
3  apis/  controllers/  helpers/  models/  views/

Within this directory, controllers contains the functional Ruby code that drives the application, modelscontains a description of the database, and views contains .rhtml template files that control the visible HTML output of the methods. There is one template for each method of our application.

What else? log contains logs, doc will contain documentation. script contains some helpful executable scripts for working with Rails. config contains configuration info, which we’ll set up right now.

config/database.yml is a YAML file that tells Rails where the database is. We open it in a text editor and modify the first stanza to reflect the database we created above:

01 development:
02
03    adapter:mysql
04
05    database:bookmarker
06
07    host:localhost
08
09    username:root
10
11    password:''s3cr3t''

Next we use one of the included tools to generate the components of our application:

1 $ ruby ./Bookmarker/script/generate scaffold Bookmark

Models are capitalized, controllers are not. Don’t ask me why. Again, if your app delivers synergetic enterprise solutions leveraging seminal proto-alternative band fIREHOSE, you’re on your own.

We have just created a controller, a model and a handful of views. Let’s fire up WEBrick, Rails’ built-in web server software, on port 3000, so we can check out the site we just MADE! For the record, make sure there’s no firewall between you and WEBrick.

1 $ ruby ./Bookmarker/script/server

Now we point our browser to http://oursite.org:3000/bookmarks (because “bookmarks” is the name of thecontroller) and wow! We have a working bookmark manager. The scaffolding we created with a single line of typing already includes functions to create, delete and edit bookmarks. Stop the stopwatches! Do you see yet why people say this is easy? All that remains is customization.

 

Steps three and beyond:Customize the application

All the functions of the application — create, edit, destroy — are Ruby methods, defined inapp/controllers/bookmarks_controller.rb, and each is displayed by an .rhtml template in themodels directory. The core of Rails development involves modifying these files with custom code, to turn a basic Show-Edit-Destroy database front-end into a Ta-Da List. Let’s add a clickable link to each bookmark that points to the relevant URL. Let us take a look at views/list.rhtml.

Ruby’s .rhtml templates are Embedded Ruby, which uses  %= and  % tags to interpolate Ruby code into HTML documents. The former is used when you want the Ruby’s output displayed in the browser, the latter when you just want to run some method behind the scenes and not output anything. So inviews/bookmark.rb, we see:

1 <td><%= link_to 'Show', :action => 'show', :id => bookmark
2
3 %></td>
4
5 <td><%= link_to 'Edit', :action => 'edit', :id => bookmark
6
7 %></td>

That code, which runs once for each bookmark in the database table, uses Ruby’s link_to() method to create a href link tags on the page that invoke the show and edit methods. Let’s add another link, pointing to the bookmarked page, for each bookmark:

1 <td><%= link_to 'Open', bookmark["url"] %></td>

Simply enough, that creates a link whose text is “Open” and whose target is the URL value for the current bookmark.

Let’s look at one slightly more complicated example before we go our separate ways today. Since the bookmark manager just has users typing in URLs, we should check (at the very least) whether they have an “http://” prefix already before throwing up a link to them. As with many commonly desirable features, Rails has a pre-existing way to do that. In models/bookmark.rb, we add a method call to the class definition:

1 validates_format_of :url, :with => /^http:///, :message => "needs to begin with 'http'."

Now, when the user tries to create a new bookmark, that method will check the URL attribute against the regular expression, and, if it doesn’t begin with “http://”, then our little error message will be displayed. Documentation for the validates_format_of() method is available on the application site.

Go ahead and keep polishing the bookmarker app. Learn some Ruby — it almost learns itself! Add CSS topublic/stylesheets/scaffold.css, add new functionality to the controller, modify the database model, hook in an Ajax bookmarklet, whatever you’d like.

Rails’ cleverness — things like auto-naming submit buttons after their actions — and Ruby’s flexibility — you can rewrite any method you don’t quite like — form a powerful combo. Because of Ruby’s reasonably intuitive way of doing things, getting from a starter scaffolding to a finished application is a short and pleasurable journey. If Rails sometimes seems like a domineering older sibling, insisting that you build your project the way it wants you to, well then, both of you probably still have some growing to do.