Cover image for Django Tutorial #3: Database Structure

Django Tutorial #3: Database Structure

ericnanhu profile image Eric Hu Originally published at techjblog.com ・4 min read

For a simple blog, we need at least 4 database tables: Users, Categories, Tags, and Posts. If you want other functions for your blog, comments, for example, you can add other tables yourself.

But to keep this tutorial short and easy to understand, these four are all we need. And since the model for the users table is already included in Django, we’ll skip it here.


Categories Table

Column Type Extra Info
index integer auto increment
name string cannot be empty
slug string unique, cannot be empty
description text can be empty

Tags Table

Column Type Extra Info
index integer auto increment
name string cannot be empty
slug string unique, cannot be empty
description text can be empty

Posts Table

Column Type Extra Info
id integer auto increment
title string cannot be empty
slug string unique, cannot be empty
featured image string or text can be empty
content text cannot be empty
published boolean
featured boolean
time stamps created at and updated at



Define Models

As we mentioned in the previous section, models interact with database tables, and each model has a corresponding table. Unlike Laravel, Django is able to generate migration files based on the models automatically. That spares us the trouble of writing separate migration files.

In Django, all of the models are in one file, model.py.


from django.conf import settings
from django.db import models

# Create your models here.
class Category(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField()
    description = models.TextField()

Line 1 and 2, import the necessary packages.

Line 7, CharField() creates a column of type string.

For other model field types, check the Model Field Reference.


class Tag(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField()
    description = models.TextField()


class Post(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField()
    content = TextField()
    featured_image = models.ImageField(upload_to='images/')
    is_published = models.BooleanField(default=False)
    is_featured = models.BooleanField(default=False)
    created_at = models.DateField(auto_now=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    tag = models.ManyToManyField(Tag)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

Line 9, 10 and 11 define the relationships between the models.

Line 9, create a column “category” that stores the index of the category that this post belongs to. Same with line 11. settings.AUTH_USER_MODEL is the User model that is predefined in Django.


python manage.py makemigrations blog

This command creates the migration files for the blog app based on the models we just created.

python manage.py migrate

This command applies all the migrations to the database. The default database is SQLite. No user name or password required. However, if you are trying to create a bigger project, I suggest using MySQL or PostgreSQL. Follow the instructions and setup your database.

Some Common Model Field Types and Options

Field Types


class CharField(max_length=None, **options)

A string field, for small- to large-sized strings.

For large amounts of text, use TextField.


class TextField(options)

A large text field. The default form widget for this field is a Textarea.

If you specify a max_length attribute, it will be reflected in the Textarea widget of the auto-generated form field. However it is not enforced at the model or database level. Use a CharField for that.


class SlugField(max_length=50, **options)

Slug is a newspaper term. A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs.

Like a CharField, you can specify max_length (read the note about database portability and max_length in that section, too). If max_length is not specified, Django will use a default length of 50.


class FileField(upload_to=None, max_length=100, **options)

A file-upload field.


class ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)

Inherits all attributes and methods from FileField, but also validates that the uploaded object is a valid image.

In addition to the special attributes that are available for FileField, an ImageField also has height and width attributes.


class DateField(auto_now=False, auto_now_add=False, **options)


Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps.


Automatically set the field to now when the object is first created. Useful for creation of timestamps.

Field Options



If True, Django will store empty values as NULL in the database. Default is False.



If True, the field is allowed to be blank. Default is False.



The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.



If True, this field must be unique throughout the table.

In the next section, we’ll talk about the admin panel, which, unlike Laravel, comes with the Django package.

Next Post: Django Tutorial #4: Admin Panel

Related Articles

How to Make Your Server More Secure

Laravel Tutorial For Beginners

Django Tutorial For Beginners

Posted on by:


Editor guide