Django & Python Adventure Part 3

If you’ve just jumped in, this is my blog series of my walkthrough of a fantastic book on learning Django w/Python called “Django 1.0 Web Site Development” by Ayman Hourieh.  I’m doing this to pick up a lot of good information: knowledge of Python, knowledge of Django, and knowledge of MVC.  Nice that I can do all three in one book.  The blog posts are so I don’t forget it and hopefully to highlight a great resource.

Our original page has HTML in the main page and that’s something we don’t want.  So, now we’ll be taking it to the next level with Templates.  Go to your project folder and create a folder called “templates”.

Now edit your settings.py

At the top add this like:

                Import os.path

Look for this section:

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.
)

Add this line inside:

                os.path.join(os.path.dirname(__file__),'templates'),

Now create a main_page.html inside the templates folder and paste this in:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
                <title>{{ page_title }}</title>
</head>
<body>
<h1>{{ page_title }}</h1>
<p>{{ page_body }}</p>
</body>
</html>

Now let’s jump into bookmarks/views.py

 

from django.http import HttpResponse
from django.template import Context
from django.template.loader import get_template
# Create your views here.
def main_page(request):
    template = get_template('main_page.html')
    variables = Context({
        'head_title': u'Django Bookmarks',
        'page_title': u'Welcome to Django Bookmarks',
        'page_body': u'Where you can store and share bookmarks!'
    })
    output=template.render(variables)
    return HttpResponse(output)

Great, now go back to your web page and hit refresh.  You should see almost the same thing without the “seriously”.

 

Next I’m writing a view for the User to see his/her Links.

So, first we’ll create the URL:

Go to urls.py and add a new pattern line under the main page pattern:

                (r'^user/(w+)/$', user_page),

Regular expressions sure are ugly looking, but they are so useful, you just have to use them J

Now go back to bookmarks/views.py to add the User Page view:

from django.http import HttpResponse, Http404
from django.template import Context
from django.template.loader import get_template
from django.contrib.auth.models import User
# Create your views here.
def main_page(request):
    template = get_template('main_page.html')
    variables = Context({
        'head_title': u'Django Bookmarks',
        'page_title': u'Welcome to Django Bookmarks',
        'page_body': u'Where you can store and share bookmarks!'
    })
    output=template.render(variables)
    return HttpResponse(output)
def user_page(request, username):
    try:
        user = User.objects.get(username=username)
    except User.DoesNotExist:
        raise Http404(u'Requested user was not found.')
    bookmarks = user.bookmark_set.all()
    template = get_template('user_page.html')
    variables = Context ({
        'username':username,
        'bookmarks':bookmarks
    })
    output=template.render(variables)
    return HttpResponse(output)

Time to design that new template.  In templates/ add a page called user_page.html.  Give it this code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Django Bookmarks - User: {{ username }}</title>
</head>
<body>
<h1>{{ username }}'s Bookmarks</h1>
{% if bookmarks %}
<ul>
{% for bookmark in bookmarks %}
<li><a href="{{ bookmark.link.url }}">{{ bookmark.title }}</a></li>
{% end for %}
</ul>
{% else %}
<p>You have no bookmarks!</p>
{% end if %}
</body>
</html>

Now you can browse to your original users page and see what’s going on:

Not a whole lot apparently so let’s jump back to the command prompt, open a database shell and fill in some real data:

If you’ve closed it, no worries, open a command prompt and browse to your PythonXX folder

Run these commands:

python manage.py shell
>>> from django.contrib.auth.models import User
>>> from bookmarks.models import *
>>> user1 = User(username=u'mdhall')
>>> user1.save()
>>> user2 = User(username=u'lahall')
>>> user2.save()
>>> User.objects.all()
[<User: sa>, <User: mdhall>, <User: lahall>]
>>> user1 = User.objects.get(id=2)
>>> link1 = Link.objects.get(id=1)
>>> user1.bookmark_set.all()
[]
>>> bookmark = Bookmark(
... title=u'Mike Hall website',
... user=user1,
... link=link1
... )
>>> bookmark.save()
>>> user1.bookmark_set.all()
[<Bookmark: Bookmark object>]

So, what just happened:  we opened the “django database shell”, created two users, grabbed the 2nd user, grabbed the 1st link (we created that in our previous part), then we created a new Bookmark (cross-reference or many-to-many table) linking the user to the link.

So, now we can go to the browser and check on the user page for mdhall:

Big fun!  Next time we’ll get into user registration and management.

Django & Python Adventure Part 2

Hello again.  Today we’ll continue from Part 1 and create an initial Template and some database Models.  Django is MVC, it just calls it MTV.  So, Model-View-Control = Model-Template-View.  I think the View part is what’s most confusing, but, that’s how it is.

Well, on with it then.  First we’ll be creating the main page view:
Open a command prompt and get to your bookmarks project again (remember you still should have another command prompt running the built in Django web server).
Type: python manage.py startapp bookmarks
Look familiar? It should.

Now you will have a folder in your application called bookmarks that contains:
your new bookmarks folder

Open the views.py in PyCharm (or whatever you’re using) and drop this code into it:

# Create your views here.
from django.http import HttpResponse
def main_page(request):
    output=u'''
        <html>
            <head><title>%s</title></head>
            <body>
                <h1>%s</h1><p>%s</p>
            </body>
        </html>
    ''' % (
        u'Django Bookmarks',
        u'Welcome to Django Bookmarks',
        u'Where you can store and share bookmarks! Seriously.'
    )
    return HttpResponse(output)

Important! Python cares a lot about indentation. If your indentation is wrong, your code won’t work.
Now open urls.py
Add an import line for your bookmarks
Add a url pattern to your main page.
r’’ means it’s a raw string. The ^$ is a regular expression which means “empty string”. In English I’m saying we just told the website what to do when the website address is just the base URL with nothing else appended.

from django.conf.urls.defaults import patterns, include, url
from bookmarks.views import *
urlpatterns = patterns('',
     (r'^$', main_page),
)

Go back and start your server and browse to your page.
Your temporary template
Hooray.

Designing an initial database (or Model) For this bookmarks website we’ll need three tables: Users, Links and a cross reference table Bookmarks Open the bookmarks/models.py page Add this:

from django.db import models
# Create your models here.
class Link(models.Model):
   url = models.URLField(unique=True)

Now open the settings.py and locate the INSTALLED_APPS section and add:

 'django_bookmarks.bookmarks',

Then pop into a command window and execute:

python manage.py syncdb

You can then validate the SQL genereated with:

python manage.py sql bookmarks

You should see this:

CREATE TABLE “bookmarks_link” (
“id” integer NOT NULL PRIMARY KEY,
“url” varchar(200) NOT NULL UNIQUE
)
;
COMMIT;

Cool? Yes, it is.
Now execute:

pyhton manage.py shell
from bookmarks.models import *
link1 = Link(url=u’http://michaeldukehall.com’)
link1.save()
link2 = Link(url=u’http://hak5.org)
link2.save()

Now you have some data in your Link table/model and you can view it with:

link2.url

or

links = Link.objects.all()

for link in links:

print link.url

or

Link.objects.get(id=1)

and

Link2.delete()

and

Link.objects.count()

Okay, well, that was a lot of fun. SQLLite via Python shell. No SQL necessary because of the Object Relationship Manager in Django. If you switch to another db, the ORM does the heavy lifting for you. So, in .Net you have to know C# and SQL. In Python you have to know Python. Win.

The User model is already created, so, we move onto the Bookmarks model.
Go back to models.py and drop this in:

from django.db import models
from django.contrib.auth.models import User
# Create your models here.
    class Link(models.Model):
    url = models.URLField(unique=True)
class Bookmark(models.Model):
    title=models.CharField(max_length=200)
    user=models.ForeignKey(User)
    link=models.ForeignKey(Link)

That imports the built in User table/model and builds the Bookmark table with foreign keys in Link and User.

Fun stuff!

In part 3 we’ll do the template properly.

Django & Python Adventure Part 1

Django & Python Adventure Part 1

Prenote: If you’re on a MacBook, check out Steve’s walkthrough: http://steveyum.wordpress.com/2011/12/14/learning-django-day-1/

Why Django & Python? Seriously, I don’t need a reason to learn stuff (Codegito Ergo Sum); This one is named after a Jazz Guitarist I like, and that is pretty cool. And the language is named after an awesomely huge snake (okay, he really named it after Monty Python). There is some serious geek power happening here. I’ll have to switch if Nintendo ever releases a Zelda Framework.

Enough philosophy. Here’s what you need to do:
1. Install Python. I choose to go with Python 2.7 over 3. http://www.python.org/getit/
2. Install Django. I choose version 1.3.1 https://www.djangoproject.com/download/ (By install I mean unzip/tar/etc it to C:Django-1.3.1 or something like that)

[Super Important, Often Left Out of Walkthroughs]
Make sure you add python to your system paths! Otherwise nothing works and you’ll be frustrated until you figure that out.
It’s in your Control Panel  System  Advanced system settings (this opens a new window)  Environment Variables
Looks like:
Environment Variables

Drop down to the second section (System Variables) and find the Path and Edit it:
Go to the end and append “;C:Python27” without those quotes. Be really careful not to delete everything in there. You’ll be sad if you do.

Then get to your command line and browse to your PythonXX installation:
Run the Django admin

And type that line.

I’m following along the best rated book I could find on the subject “Django 1.0 Web Site Development”. This is the kind of book I wish I had on a lot of subjects. Not 500 pages of theory that I’m not terribly interested in or reference material that’s available through google.

Django is a Python developed Model-View-Control web framework. This is another big reason I want to learn it. In the Microsoft world, I can create a web application via Web Application, MVC Web Application, and about a dozen other ways. It’s really easy for me to not care about that, since, I’ve already grown accustomed to Web Applications in .Net and the MVC projects really don’t give me anything I don’t already have. So, This is a way for me to see how and why MVC really got big in the first place. Django was created in the bowels of a newsroom where time was essential. That sounds good to me. The MS MVC project I created didn’t really blow me away with the rapidity of anything, so, hopefully this is it.

Anyway, so that line up there generates a folder named after the project:
project folder

Now we’ll configure our database. When you downloaded Python 2.7 (anything 2.5 and up) it loads up SQLLite for you.
As far as Editors are concerned I went with PyCharm 2.0 Beta since it looks a lot like Visual Studio and is free (since it’s in Beta).
You can get PyCharm here:

Now that you’ve got it, open your project folder and edit the settings.py
PyCharm

I wanted to turn on SQLLite and create a database called bookmarksdb.
Looks like this:
DATABASES = {
‘default': {
‘ENGINE': ‘sqlite3′, # Add ‘postgresql_psycopg2′, ‘postgresql’, ‘mysql’, ‘sqlite3′ or ‘oracle’.
‘NAME': ‘bookmarksdb’, # Or path to database file if using sqlite3.
‘USER': ”, # Not used with sqlite3.
‘PASSWORD': ”, # Not used with sqlite3.
‘HOST': ”, # Set to empty string for localhost. Not used with sqlite3.
‘PORT': ”, # Set to empty string for default. Not used with sqlite3.
}
}

Then I need to get back on the console, browse to the project folder, and execute the command:
database setup

Then you’ll create a superuser for your database and that’s it.
Time to start the server:

Run this command:
Python manage.py runserver
This will start up django’s built in web server. Notice the default port is 8000. One nice thing is that the server restarts every time you modify the code, so, geaerd for easy debugging.
django project startup page

Well that’s enough for a part 1. If you have any questions or comments, shoot me an email.
-Mike

Resources:
Django Website Development 1.0
Python
Django
PyCharm

© Copyright Duke Hall - Designed by Pexeto