How to create a basic blog in Django
Django can do a lot more than just create blogging applications, however I do think this is a good place to start.
Notes
- I am going to assume you have already setup Django to run as either a development server, or configure apache/lighttpd correctly. If not please refer to “Setting up your server to run django”.
- This is a working example, although lacks some real-world functionality, these points are noted throughout as well as possible fixes.
Starting your application
Navigate to your project directory, this should contain a __init__.py
, manage.py
, settings.py
and urls.py
. There may also be a few others. For reference, my project name is djangorocks, you will need to replace any references to djangorocks throughout this tutorial.
Type the following into terminal, this creates a new application folder & key files we will be using for our blog.
python manage.py startapp blog
You should now have a folder called blog containing 3 files: __init__.py
, models.py
and views.py
.
Important
Open up your settings.py
, this is located in your project folder. Find INSTALLED_APPS
and add 'blog'
. You should have something similar to the following;
Django now knows about your new application, all thats left to do is create it.
Defining your models
The model is your database structure. Lets start by opening the models.py file, and start adding some fields. Because I am keeping this simple, I will not be including users at this stage.
Now lets see what each part means.
This creates a database table with the name “Blog”. This need to be something obvious and will be used a lot.
These are basic fields to be created in your database
The last field, a little more advanced. This field populates its data from another database table, in this case Category, so you will need to populate the Category table field first.
Finish the model
There are a few more things to be added to the model now that we have decided on the database structure. Your completed model file should look as follows.
What are all these extras for?
The __unicode__
function sets the text reference for each record. This is used mainly in the automated django admin, but this is still available to use on your own site.
The get_absolute_url function defines a URL, again used in the admin area, for each record.
Without the @permalink decorator the following would not work. This returns a URL calculated from the urls.py file which will be explained shortly. I would recommend using this method as it allows you to change the URL for a page in only one location.
Example
Title: How to create a basic blog in django
Response from __unicode__
: How to create a basic blog in django
Response from get_absolute_url
: /blog/view/how-to-create-a-basic-blog-in-django.html
Limitations from this example
- Blog has a field slug. This is used as the URL to identify the post. In this case both the title & slug field are set to unique. It is not unreasonable to have two posts with the same Title. To solve this you could set the slug field to contain the ID of the post ie. 2-my-second-post
- This example allows only one category per post. This is quite simple to change by adding a
ManyToMany
field type to category instead ofForeignKey
. The way you use this is sligthly different, so it will not work without other changes to this tutorial.
Configuring the automatic admin
In many of your own applications you will probably want to write your own administration functions, you will completely miss out this section.
Create admin.py
in blog folder we created earlier. This admin.py
file is automatically checked by django admin for every application defined under INSTALLED_APPS
in the settings.py
Now lets see what each part means.
Import the command which allows us to register the model we created
Import our models
Register our models Blog
& Category
with the admin
Although these three lines are enough to get the admin working, we want to add a little more functionality. Heres the final admin.py
.
Now that you have added these models into the admin, you might want to login and add a few categories and blog posts.
Limitations from this example
- The
prepopulated_fields
are exactly as they sound. The data for theslug
field is automatically populated by the data entered in the totitle
field. Remember this ONLY works in the django admin so if you are not using this, the slug field will not be populated. - The
excluded
field in this instance again is automatically populated with the date it was created. Remember this ONLY works in the django admin so if you are not using this, the date field will not be populated.
A good way to solve these problems is to update your models with a save
function.
Writing the views & Defining your URL’s
The view is where you do all the logic to be sent to your templates. In this example we will not be dealing with RequestContext
. This would give you access to the request
object which contains details for the currently logged in user, as well as a few other features you will be likely to use in the future.
For this example we need to create 3 views.
- Display your categories & latest posts
- Display the posts in a specific category
- Display the post
Here is a copy of the view.py
.
As with the admin.py
file we need to import the models.
We also need to import a couple of functions for displaying our template.
The following is for your index page, which will display a list of all your categories, and 5 most recent posts.
When defining functions, you always need to specify the variable request
. This is the request object, which contains details of the User, POST & GET data as well as a few other bits. In the following instance we are also specifying slug
which is mapped to from the urls.py
file as you will see in a minute
This first part sets the template file that we are going to be using.
The next part queries the database for both categories and posts. Category
and Blog
are the names of the models we created earlier. For more information on how to use objects please read INSERT A LINK HERE
In the other two functions view_post
& view_category
we use one of the rather useful django shortcuts. This queries the database trying to match where slug=slug
, the first slug
being the field in the model, the second slug
being the input into the function call, more on this in a second when we define the URL’s.
Defining your URLs
Open up the urls.py
located in your project folder, add the following 3 lines.
The first URL match is just a simple match nothing, ie http://www.yourdomain.com/, and mapping that through to the view index
. The second two have custom variables being passed to the view. There are just regular expressions with the parameter matching syntax of django.
As I always use the .html extension on my URL’s this works fine for me. This matches everything up to ‘.’, there are other ways of doing this, and it maps the result to slug
which is also the name of a parameter in the view_post
and view_category
functions.
The final part labeled name
is what we used when defining the models. get_absolute_url
returns a URL automatically calculated based on the URL that is entered here. Defining this just once means that if you change the mapping URL, it will also change throughout the site. You are also able to use the template tag that Django provides to do a similar thing, however this is not used in our example.
Writing the templates
The templating system in django is extremely powerful, we will only be using a small handful of its functionality in this example.
Firstly, lets create our base template. This is just a very basic example, which is not valid XHTML. This template alone doesn’t do a great deal.
base.html
index.html
view_post.html
view_category.html
So, what does all this do?
In the base.html
we are defining the base content, <html>
, <body>
etc, as well as the blocks we would like to display. The content for these is output based on the content that extends the base template.
On the first line of all three of the other files you will notice
This line calls the base.html
template file. Inside this we define the blocks very much the same way as in the base.html
file, however this time we add the content we want to display. Using the example from index.html
We define the block for content,
Inside here we are checking if there are an categories. The variables we use here were defined in the views.py
file in the render_to_response
function.
If there are categories, the following is run
This will loop the response from the Category
model as defined in views.py
, and print out the results that are entered into the database.
Hopefully that was useful. Want to try something else? how about creating an authentication backend.