Azeez Aremu
Django way

Django way

Django Models

Django Models

Azeez Aremu's photo
Azeez Aremu

Published on Apr 12, 2021

8 min read

Subscribe to my newsletter and never miss my upcoming articles

Hi guys, in the last article we looked into Django architecture where we stated that Django is majorly of three layers i.e Model layer, Views layer and Template layer (MVT structure).

So in this article we will look into the full gist about Django models and thus by the end of this article you should know

  • What model definition is

  • Model fields and field attributes

  • Fields relationships

why not grab a cup of coffee with a note and pen to learn one of the major layers of Django


Models Definition

According to Django documentation, Django model is defined as

The single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing.

model definition is data storage definition i.e how you want your data to be stored in the database with consideration to it's field type, field attributes, field relationships etc. Yes you guess right, all these are very easy with Django web framework. 😋

from django.db import models

class Articles(models.Model):
    title = models.CharField(max_length = 200 )
    content = models.TextField(blank=True, default="New article")
    created_on = models.DateTimeField(auto_add_now=True)

Whenever a model is defined and necessary migrations are done, a table is created with specified columns. In the above code, Django will create a table with

  • "Articles" as name

  • Three fields (columns): CharField(title column), TextField(content column) and DateTimeField(created_on column)

  • Each field has it's own attribute(s) like max_length, blank, defaults etc

Some fields requires some attributes to be defined like max_length for CharField, chioces for a Choice field else an error will be raised

Models Fields and Fields Types

Model field is the container that can store data whenever it is created. Django model fields vary as we have a series of data types and and data volume to store i.e the data type and its length will determine the field to use in holding the data in the database. In every field declaration Django picks three things which are

  • Kind of data to store in the field (strings for CharFiled, integers for IntegerField, Boolean for BooleanField etc)

  • Type of HTML widget to use when it's time to present the field as a form field ( e.g CharField uses HTML text input field )

  • Validation requirements for the field (blank,null, unique etc) before data is being saved to the database

Some of the common fields we have are discussed below

  • CharField

This field stored strings data type i.e it can store both long and short string values with the restricted length i.e each CharField is defined with a max_length of character it can accommodate. Its HTML default widget is a text input tag.

from django.db import models

class Articles(models.Model):
    # maxmimum of 200 characters will be stored
    name = models.CharField(max_length = 200 )
  • TextField

Sometimes you will have a need to store string data type of no limit, then TextField is the best to be used. Its HTML default widget is a textarea tag.

from django.db import models

class Articles(models.Model):
    content = models.TextField( )
  • IntegerField / PositiveIntegerField

Integer values between -2147483648 to 2147483647 can be stored in this field. Thus to limit the integers to be stored to only positive we have PositiveIntegerField to do that. It's HTML default widget is number input tag

from django.db import models

class Articles(models.Model):
    balance = models.IntegerField() # stores both negative and positive integers
    number_of_authors = models.PositiveIntegerField() # stores only positive integers
  • FloatField

This enables us to store float data as known in python programming language. It's HTML default widget is number input tag.

from django.db import models

class Articles(models.Model):
    price = models.FloatField()
  • DateField and DateTimeField

DateField stores the date input and the DateTimeField stores both data and time as shown below

from django.db import models

class Articles(models.Model):
    #e.g 2021-09-12 
    created_on = models.DateField()

    #e.g 2021-09-12 12:09:50
    published_on = models.DateTimeField()
  • BooleanField

This is to hold the boolean True or False values.

from django.db import models

class Articles(models.Model):
    published = models.BooleanField(default = False)

Also we have ImageFiled, FileField,DecimalFiled, EmailField, SlugField etc

Field Attributes(Options)

These are the arguments that can be used with filed types in which some are required while most are optional. Some of the common field options are

  • Blank (optional) : If set to True, the form field can be accepted from the user not filled. This is False by default and it is a purely validation-related option for Django forms.

    date = models.DateField(blank = True)
  • Null (optional): If set to True, the filed is allowed to have the NULL as a value if no input is provided when saving the instance in the database and it is database related option.

    date = models.DateField(null = True)
  • Unique (optional) : This is to ensure that the value provided is unique throughout the table

    email= models.EmailField(unique = True)

    Null is to be set to True for a CharField if both unique and blank are set to True

  • Choices (optional): This is list or tuple of tuples which are for the user to select one from or more that one if set to accept multiple choices.

    gender_choice = (("Male","MALE"), ("Female","FEMALE"))
    date = models.CharField(blank = True, chioces=gender_choice)

    In ("Male","MALE"), "Male" is the value that will be stored in the database while "MALE" is to be shown to the user.

  • Default (optional): This is the value to use for a field if no data is supplied when the new table object is created.

    from django.utils import timezone
    #current date will be stored if no date is provided
    date = models.DateField(default =
  • Help_text (optional): This is just to give more information about the filed to whoever is supplying the input.

    date = models.DateField(help_text = "Please use the following format: <em>YYYY-MM-DD</em>.")
  • error_message (optional): if stated it will override the default field's error to throw in case of error and the defined error is shown instead

    #current date will be stored if no date is provided
    date = models.DateField(error_message = "look at help text for correct and valid input")
  • Verbose name (optional): This is the human readable name for the field and if not set, Django use the field name with underscore as spaces

    date = models.DateField(verbose_name = "created date")

Fields Relationship


There are times when we need to relate tables in our database for instance let say we have a car table which holds information about the manufactured cars and also another manufacturer table which holds information about car manufacturer and thus we are now in need to connect car(s) objects created with certain manufacturer(s). This can be achieved with Django models relationship.

Yes it can be done in Django very easily when it comes to relating tables in the database and thus a table can have access to the fields value of another table it is connected to. We have three major ways of connecting tables which are

  • ForeignKey (ManyToOne or OneToMany)

This relationship is used when we need to connect a table to many records in the other table, for instance we know a car can have just one manufacturer but a manufacturer can have many cars and so between car and manufacturer a ManyToOne can be used as shown below.

 from django.db import models

 class Manufacturer(models.Model):
     name = models.CharField(max_length = 100)
     address = models.CharField(max_length = 200)
     email_address = model.EmailField()

 class Car(models.Model):
     name = models.CharField(max_length = 100)
     manufacturer = models.ForeignKey(Manufacturer, on_delete = models.CASCADE)
     date_released = models.DateField()

The tables are connected with the ForeignKey field and thus when a car is created, it is connected to a manufacturer and thus it has access to it's manufacturer details (name, address and email_address)

on_delete option is required for ForeignKey field and thus it can be set to models.CASCADE, models.SET_NULL, models.PROTECT, models.DEFAULT, models.SET() or models.DO_NOTHING

models.CASCADE means when the associated manufacturer is deleted from the database the car should also be deleted automatically.

models.SET_NULL means when the associated manufacturer is deleted, the car object should be retained with the manufacturer column set to NULL.

models.PROTECT is use to protect the car object from deletion when the manufacturer is to be deleted by not allowing the manufacturer deletion.

models.DEFAULT is used to set a certain value for the car object when the manufacturer related object is deleted.


  • ManyToManyField

Now instead of making one table has access to records in the other table, we might want both tables to have access to records in each other table, to do this a ManyToManyField is used. For instance, a user can read as many as possible articles and an article can be seen by many users.


 from django.db import models

 class users(models.Model):
     name = models.CharField(max_length = 200 )

 class Articles(models.Model):
     title = model.CharField(max_length = 200)
     viewed_by = models.ManyToManyField(users, blank = True)
  • OneToOneField

This is the relationship needed when we solely need a record in a table to access one record in another table. For instance, let's say an author is restricted to write one article and thus a OneToOneField can be used. i.e whenever we create an article a new author is expected to be created.

from django.db import models

class Reporter(models.Model):
    name = models.CharField(max_legth = 255)
    address = models.TextField()

class article(models.Model):
    reporter = models.OneToOneField(Reporter, on_delete = models.CASCADE)
    title = models.CharField(max_length = 255)


Wow 👍 well done for making it to the end. I guess some clarifications have been made to some things regarding Django models. In the next article we will get our hands dirty and actually code in Django and see these models in action.Thank you for reading.

Visit Django models documentation for more details.

Share this