Today we’ll be learning the gist of Django, a pythonic web framework. In the spirit of a stereotypical web framework django tutorial, we’ll produce a primitive blog with the minimal amount of code possible. Yellow background color text indicates text to be entered into a command line/terminal and blue indicates code. If you’ve followed my django screencast, you’ll be familiar with the most of what this tutorial covers. However, I’ll explain the code in this tutorial in more depth than I did in the screencast. If you like to know what everything does, this article is for you.
If you’ve never dealt with (or even seen) python code before, I recommend skimming through python’s official tutorial. The most notable difference between python and most other languages is that tabs/spaces are used to indicate code blocks. So an if statement would look something like this:
if myvariable == True:
print “myvariable is True”
print “Always printed”
One other thing to note is that boolean variables are True and False (case-sensitive). It’s also a good idea to dust off your terminal / command line skills (cd, ls, etc.).
If you’ve followed another django tutorial, you’re all set. Otherwise here’s some brief steps to follow.
Alternatively, you could try using a DjangoStack installer, but I’ve never used one so I can’t say how easy or hard it is.
Unless you’ve been hiding under a rock or are completely new to the web development community, you know that Model-View-Controller (MVC), is the latest craze is the web world. This provides a clean separation among:
Django is quite similar, although it uses the name MTV (Model-Template-View) instead. This is slightly confusing for people coming from other MVC frameworks since a MVC Controller is a View in Django and a MVC View is a Template in Django. I’ll be referring to everything in terms of Django’s MTV in the remainder of the tutorial.
Django templates have their own template language which is relatively easy to grasp for programmers. It’s catered for web designers (not programmers) to manage logic that directly deals with how to display data. The templating system is designed to be as minimal as possible and specifically excludes any feature that doesn’t relate to the display logic (e.g. variable assignments are not allowed). Although the templating system could be extended to implement such features, most of that code really belongs in the view.
For more information, you can see the entire laundry list of Django’s philosophies.
I prefer to run instead of walk first, but that’s just me. Let’s create a django project using django-admin.py startproject myblog to create a myblog directory containing our django project.
What are these files?
|
We’ll edit settings.py and enter our database information:
DATABASE_ENGINE = ‘sqlite3′
DATABASE_USER = ‘sqlite.db’
Fill in other database information if your database engine requires it (which is anything other than sqlite3). You can edit your TIME_ZONE to be closest to your server location (or your location if you’re running it locally), but it doesn’t really matter too much for us.
File paths in settings.py must be absolute. This is because a relative path isn’t explicit (one of python’s philosophies) since it could refer to either where django’s site-package location (where some provided addons reside) or your current working directory (where you executed the command to start the server) or your project directory. Instead paths are all absolute. Since we’re going to make all our relative paths relative to the project directory, or settings.py to be more precise, we’ll add the following code snippet to the top of our settings.py to automatically convert all our relative paths we specify to absolute paths.
import os
rel = lambda *x: os.path.join(os.path.abspath(os.path.dirname(__file__)), *x)
The first line imports the python-provided os module which provides us with path-related functionality.
The second line is a bit more complicated to gobble. We’re creating a lambda/anonymous function named rel. In python, lambda functions are usually short one-liner functions that have to return a value, which also explains the reason why there’s no return keyword (the expression is implicitly returned). As part of the lambda definition, we accept any amount of arguments which is stored in array x.
We then join a series of paths (which will figure out the appropriate directory separator based on the operating system) which includes the absolute path determined by the directory name where this file resides (settings.py) and any directories we provide in the function parameters. *x expands the x array and passes to the function as parameters.
Now we can provide relative directories from our project directory. Let’s specify those now in settings.py. Make the following changes (or change them to whatever you feel is right):
MEDIA_ROOT = rel(‘media’) # media subdirectory in the project directory
MEDIA_URL = ‘/resources/’ # for the variable we get to use in templates, later
TEMPLATE_DIRS = (
rel(‘templates’),
)
If you wanted all the media and templates in one directory you could do something like:
MEDIA_ROOT = rel(‘resources’, ‘media’)
MEDIA_URL = ‘/resources/’
TEMPLATE_DIRS = (
rel(‘resources’, ‘templates’),
)
Save, and we’re good for now.
What good is a blog without any posts? Our first application will provide the framework for a blog post. So in the project directory execute django-admin.py startproject posts or python manage.py startproject posts to create a subdirectory and application names posts.
The following files in the new directory are as listed:
Before we implement anything else, we should probably create the models for our app. Our post model is going to be minimalistic. So open up models.py and append the following:
from django.contrib.auth.models import User
class Post(models.Model):
author = models.ForeignKey(User, related_name=’posts’)
title = models.CharField(max_length=200)
body = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
up_date = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.title
This is presents our data for our model which inherits from django’s Model class. The first line imports the django-provide User model, which adds users support for our project, including authentication and permissions. But in this case, we’re using it to associate a user who creates a post to be the author of it. The named key parameter related_name is the variable name the User model should have to store the list of posts. By default it is <model_name>_set, but here we’re specifying it as posts.
Each post will have a title field which is a database char field whose max length is 200. This is validated both via the database (assuming you use Django to create the tables) and by Django when the model is saved. The body field is self explanatory, create a field to store a large string of text. Pub_date and up_date store datetime fields in the database. The auto_now_add keyword parameter sets the field to the current date time when the model is being added to the database (not when saving changes). Likewise, auto_now applies the current datetime whenever the model is saved.
Finally, we have a __unicode__ method defined. This is simply a unicode string to return when a post instance is requested to be displayed automatically.
That’s all the models we need!
Next, we’ll need to add our application to our project. Add the following line to your INSTALLED_APPS variable in settings.py:
‘posts’, # whatever you named your application
So you INSTALLED_APPS should look something like this:
INSTALLED_APPS = (
’django.contrib.auth’,
’django.contrib.contenttypes’,
’django.contrib.sites’,
’posts’,
)
It is worth noting that applications are loading in order they are listed. So your applications should always be at the end since they’ll usually depend on Djangos’ built-in applications.
We can tell Django to create all the tables in INSTALLED_APPS based on what the models defined. This can be done with python manage.py syncdb.
When creating tables for django.contrib.auth, it asks you to create a superuser, do so since it’ll allow you to login in the admin interface we’ll be discussing in the next section.
We will be continuing Part II tomorrow so stay tuned by subscribing to the RSS Feed
[...] A Detailed Django Tutorial: Blog Basics Part I (tags: python django web programming blog) [...]
[...] Part 1 [...]
DATABASE_USER = ‘sqlite.db’ should be:
DATABASE_NAME = ‘sqlite.db’
django-admin.py startproject posts or python manage.py startproject posts
should be startapp. i’m guessing your brother didn’t actually work through the tutorial…
HI,
I am having trouble understanding the model.py.
It refers to User, and I don’t know what User looks like.
Any help pleas
yes joel is right. your brother has made you fool, haha. nice tutorial btw
Creating Our First Application
What good is a blog without any posts? Our first application will provide the framework for a blog post. So in the project directory execute django-admin.py startproject posts or python manage.py startproject posts to create a subdirectory and application names posts.
ITs not STARTPROJECT its STARTAPP
Sorry about being late. (There really needs to be some email notifications via comments).
Yeah, due to some miscommunication, my brother actually didn’t read through the whole thing before I published it. My bad
Thanks joel and scott for pointing out the typos.
Hi,
Nice tutorial… Thanks!
For future noobs that do not read comments first, it might be good if you fix your tutorial to say “startapp” vs. “startproject”. That took me a few to figure out due to my noobiness.
Another problem with this article is that all the single quotes have been changed to apostrophes, which breaks all the code.
Why don’t you fix these problems in your posts rather than just acknowledging them in the comments?
October 11th, 2009 at 11:51 pm
[...] See the article here: By: nick [...]
October 21st, 2009 at 11:58 pm
In advance, sorry for my english.
Congratulations on the article.
Can I bookmark this and then mention it on my blog?
go for it!
December 14th, 2009 at 12:40 am
…So in the project directory execute django-admin.py startproject posts or python manage.py startproject posts …. should be
python manage.py startapp posts
I’d say great tutorial but I am wary of following it due to not wanting to waste my time if there are so many issues on the first page, I am wondering what it’s going to be like later on??
Also, I agree with folks before me – if someone points out issues, some glaring ones at that, doesn’t it make sense to correct them in the post? Seems to go against the whole point of posting a tutorial if you don’t fix the mistakes.
Sorry to be negative. Really appreciate that you’ve put this up for us all but if you’re going to do it, do it right
Thanks for this post. I am new at python and this will help a lot.
Cool Thanks for your post. I am starting django and this got me straight.
I used the Django 1.1.1 and this line
DATABASE_USER = ’sqlite.db’
must be
DATABASE_NAME = ’sqlite.db’
You could have a excellent method of placing elements into viewpoint.
“Why don’t you fix these problems in your posts rather than just acknowledging them in the comments?”
This.
[...] 5. Brenelz: A Detailed Django Tutorial [...]
For future readers, could you correct the errors in this post? I can easily imagine some people banging their heads against a table for hours trying to work through some of the errors here.
below line returs with error on Eclipse.
author = models.ForeignKey(User, related_name=’posts’)
What exactly is better programming language to start off with java or vb?
September 23rd, 2010 at 4:01 am
[...] Bernelz – Detailed Django tutorial – blog basics: Again, a four part tutorial that teaches one how to create a basic blog site using Django. This [...]
To solve these cases, where you would like to assign empty strings to the extra variables (and eliminate errors), append a delimiter string to the string as follows.
December 15th, 2010 at 11:44 pm
Hey, great post. I’ll definitly be bookmarking this.
I was just thinking about that, hmm interesting I wonder. Well thanks for the post really handy, to me anyway.
What exactly is better programming language to start off with java or vb? Can we build facebook sites off of this?
Hi!
Thanks for a good article. By the way: is it an error in ”
We’ll edit settings.py and enter our database information:
DATABASE_ENGINE = ‘sqlite3′
DATABASE_USER = ‘sqlite.db’ <<<HERE?"
AFAIK it should be empty for sqlite3.
Correct me if I am wrong.
Thanks!
September 6th, 2011 at 2:24 pm
I think Jurij Ghirin is right – leave it empty and it will work!
[...] 5. Brenelz: A Detailed Django Tutorial [...]
November 26th, 2012 at 11:27 pm
It’s great that you are getting thoughts from this post as well as from our dialogue made at this time.
good work…….
Twitter
Follow me on Twitter to keep up to date!
RSS Feed
Keep up with all of our updates by subscribing to our RSS feed!
FaceBook
Join our group on Facebook and become a fan of us!