In part 1 of this Django tutorial series: introduction to Django, we introduced you to Django, popular sites using Django and what can Django do, in part 2, we showed you how to install Django in a virtual environment and in part 3, we showed you Part 3: how to create an hello world site.

Django comes with Models which is a layer to create your database tables. In this beginner Django tutorial series part 4, we will show you how to create and work with Django models. This is a Django tutorial series, so if you haven’t read part 3, then see Part 3: how to create an hello, world! site to get started.

What is a Django Model?

To create a dynamic website (one that interacts with a database), one will have to learn SQL which stands for Structured Query Language, used for Creating, Reading, Updating and Deleting data (CRUD operation) in a table. Learning and mastering SQL requires a lot of time invested, because it comes with several complicated statements for each operation one would want to perform. Django solves this hassle by introducing the concept of Models. Django models solve this problem by organizing models into tables, and mapping them into databases without writing any SQL query.

A model is an entity which is automatically turned into a database table. It is basically your database layout which is used to automatically generate database tables for your Django app. Django allows you to define models (database tables) in the models.py file of your Django app. Django uses models to create tables, database constraints and fields.

Creating a Model in Django

Django models are defined in the models.py file of your Django app. A typical Django model looks like this:

from django.db import models
from django.urls import reverse

class ModelName(models.Model):
  field_name = models.CharField(max_length=30)
  another_field_name = models.TextField()

  # Methods
  def get_absolute_url(self):
    return reverse('detail-view', args=[str(self.id)])

  def __str__(self):
    return self.field_name

The first line imports models from django.db, and reverse from django.urls. The reverse function will be used to return the reverse form of a URL from a view that is mapped to a URL.

The ModelName model is a database table, and it subclasses the django.db.models class. It provides Django with a lot of information, and allows Django to create a database layout or schema using the CREATE TABLE statement in SQL. The ModelName is basically a database table.

field_name and another_field_name are to be replaced with the name you want to call those fields. They are attributes, which basically represent database fields. field_name uses CharField(), which is similar to the HTML input element, while another_field_name uses TextField(), which is similar to the HTML textarea element. Each of the fields is mapped to the ModelName model, which is a database table.

Django model fields accept arguments which allows you to specify additional information for the field. Additional information like: max_length – for specifying the maximum number of characters such field can hold, etc. More on this in a bit!

Django Model Methods

You can define methods to use inside of the Django model. In our example, we defined the get_absolute_url() method, which returns a full form of your URL.

The __str__ method is a magic (or dunder) method in Python. It returns the string that will be used to display the ModelName model objects in the Django admin site.

In a standard Django model, you should always define the __str__ method. The __str__ method returns the human-readable string representation for each object of a model.

When working with Django models, note that:

  • Each model is a Python class that subclasses django.db.models
  • Each model maps to a single database table
  • Each attribute in a model basically represents a database field.

Notice we didn’t add an id field, this is because Django automatically creates it for us.

Defining the Blog Model

For this Django tutorial series, we will create a blog in Django. So, in this section, we will define the blog model that will be used for this tutorial series. Open the models.py file in your blog app. You will see:

from django.db import models

# Create your models here.

Update it by adding two more imports on the next line, like below:

from django.urls import reverse
from django.contrib.auth.models import User

Creating The Category Model

The Category model is a database table that will store the categories each blog post belong to. Copy and paste in your blog’s models.py file:

class Category(models.Model):

  title = models.CharField(max_length=200)
  description = models.TextField()
  created_at = models.DateTimeField(auto_now_add=True)
  updated_at = models.DateTimeField(auto_now=True)

  def get_absolute_url(self):
    return reverse('category-detail', args=[str(self.id)])

  def __str__(self):
    return self.title
  • title – This field will hold each category title. It has CharField() as the field type with a max_length of 200. The max_length argument or field option is required for a CharField().
  • description – This field will hold the description of each category. It has the TextField() field, which is similar to the HTML textarea element.
  • created_at – The created_at field has a DateTimeField() field, which will store the date and time each category was created. It has auto_now_add=True, meaning that the current date and time will be used on this field when a category is created.
  • updated_at – This field will store the date and time the category was edited or updated. It has a DateTimeField() field, and auto_now=True field option, which means that each time a category is updated, this field will be updated with the current timestamp.
  • After that, we created a get_absolute_url() and returned a reverse (we imported), with category-detail as the view name and self.id as the args (arguments). self.id points to the id field in the category model which Django automatically creates for us. The id field is unique!
  • Next we defined the string (__str__() method) representation of the object in the Category model. We returned self.title which is the title field of the Category model.

Creating The Article Model

The Article model is a database table that will store the articles or blog posts. Copy and paste in your blog’s models.py file.

class Article(models.Model):

  author = models.ForeignKey(User, on_delete=models.CASCADE)
  title = models.CharField(max_length=200)
  content = models.TextField()
  category = models.ForeignKey(Category, on_delete=models.CASCADE)
  created_at = models.DateTimeField(auto_now_add=True)
  updated_at = models.DateTimeField(auto_now=True)

  def get_absolute_url(self):
    return reverse('article-detail', args=[str(self.id)])

  def __str__(self):
    return self.title
  • author – The author field will store the author of each article. It has a ForeignKey relationship pointing to the built-in Django User model (we imported earlier), and on_delete=models.CASCADE, which means delete every article that belongs to this user when the user account is deleted
  • title – This field will hold each article title. It has CharField() with a max_length of 200. The max_length argument or field option is required for a CharField().
  • content – This field will hold the content or body of each article. It has the TextField() field, which is similar to the HTML textarea element.
  • category – The category field will store the category each article belong to. It has a ForeignKey relationship, which points to the Category model we defined earlier, and on_delete=models.CASCADE, which means delete every article that belongs to this category when this category is deleted
  • created_at – The created_at field has a DateTimeField() field, which will store the date and time each article was created. It has auto_now_add=True, meaning that the current date and time will be used on this field when an article is created.
  • updated_at – This field will store the current timestamp the article was edited or updated. It has a DateTimeField() field, and auto_now=True field option, which means that each time an article is updated, this field will be updated with the current date and time.
  • We created a get_absolute_url() method and returned a reverse (we imported), with article-detail as the URL name and self.id as the args (arguments). self.id points to the id field in the article model which Django automatically creates for us.
  • Lastly, we defined the string (__str__() method) representation of the object in the Article model. We returned self.title which is the title field of the Article model.

Migrating the Models

If the development server is still running, press ctrl + c to stop it. Run the following command to create migrations for the changes in the models.py file:

python manage.py makemigrations

The makemigrations command creates migration for the changes made in the Django models.py file. Migrations are created from Django models, and are basically a history that Django can roll back to, to update the database layout or schema to match the current changes in the models.py file.

The following should be the result in the terminal or command prompt:

Migrations for 'blog':
  blog\migrations\0001_initial.py
    - Create model Category
    - Create model Article

After that, run the following command to make the actual changes to the database:

python manage.py migrate

The migrate command applies the actual changes to the database.

The following should be the result in the terminal or command prompt:

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

Since this is the initial migration, it creates all of the required tables you need to work with Django.

Django Fields

Earlier we looked at the CharField(), TextField(), etc., as some Django supported fields. There are many other field types in Django. The following are the supported field types in Django:

  • AutoField – This is an auto-increment integer field.
  • CharField – This is a character field, it accepts a max_length argument, which specifies the length of characters it can hold. You can see the CharField() field as the equivalent of the HTML input element.
  • DateField – This field is responsible for storing dates.
  • EmailField – This is similar to the CharField(), except that it accepts Emails alone, that is; it checks if the email you enter is a valid Email address.
  • FileField – The FileField() allows you store media content references.
  • ImageField – This is a reserved field for storing images only.
  • IntegerField – This is a number field that is reserved for whole numbers alone.
  • SlugField – This is a CharField() field that allows you store slugs. If you are storing a slug/permalink, then you need the SlugField.
  • TextField – The TextField() is a large text field for storing large volume of text like blog posts, product descriptions, etc. It is similar to the CharField(), except that it can hold large volume of words/characters. You can see the TextField() as the textarea element.
  • TimeField – This field is responsible for storing time.

Django Relationship Fields

Django models also allow you specify relationships between models. The following are the supported relationship types in Django:

  • OneToOneField – Any field in the Django model that has a one-to-one relationship means that it can hold only unique data (no duplicates) in that field. This means that one item can have only one other item that is related in a table, and it must be unique throughout the one-to-one field/column. It is like passing Unique=True argument to a field. This enforces uniqueness in such field.
  • ForeignKey – A ForeignKey or many-to-one (also called one-to-many) relationship is similar to the one-to-one relationship, except that it can hold duplicate data compare to the one-to-one relationship. This type of relationship means that one item can have many other related items in a table (duplicates inclusive).
  • ManyToManyField – The many-to-many relationship is like the many-to-one or ForeignKey relationship, except that a car can have several car models, and each car model can have several cars. This type of relationship is independent compare to ForeignKey and OneToOne relationship.

Django Field Options

Django field options or field arguments allow you pass extra behavior to a field. The following are the field options in Django:

  • blank – This means that this field can be left blank. It accepts a boolean value of True or False. If you are passing blank=True, then it is recommended you also pass null=True to the same field.
  • null – This field can store null values (empty) in a field. It accepts a boolean value of True or False. If you are passing null=True, it is recommended you also pass blank=True to the same field.
  • default – This field argument allows you give your field a default value, and is used when no value or data is inputted. default=’This is a demo text when nothing is typed’.
  • editable – This allows you specify if or not the field should be editable. It accepts a boolean value of True or False. By default, the updated_at = models.DateTimeField(auto_now=True) field has editable=False, which makes it impossible to edit.
  • help_text – The help_text field option allows you specify a guide or hint text on what the field is all about. help_text=’Please use CAPITAL LETTERS’.
  • max_length – The max_length Django field option is needed when using the CharField() field. Since the CharField() is like the input element, it needs a limit.
  • unique – This specifies if this field should be unique. It accepts a boolean value of True or False. If unique=True then this field will be unique throughout the table, and no duplicates will be stored.

Django Tutorial Series

In this Django tutorial series, we have been able to cover part 1 – part 3. If you need to read them again, please see:

We hope this Django tutorial series – creating and working with Django models (Part 4) helped you learn how to create a Django model, relationship fields, field options, etc. This is a Django tutorial series, so if you haven’t read part 2, then see Part 3: how to create an hello, world! site to get started.

See other of our Django tutorials for more.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.