Mike Slinn
Mike Slinn

Django Model Notes

Published 2021-02-12. Last modified 2021-06-09.
Time to read: 2 minutes.

This page is part of the django collection, categorized under Django.

Creating Model Instances

Here is a tiny Django model class definition with one field:

from django.db import models
class MyModel(models.Model): field1 = models.TextField()

Python's standard instantiation works as usual for model classes; it creates an instance in memory but does not persist it to permanent storage. Calling save() on the instance persists it.

The objects.create factory method provided by Django model classes automatically persists new instances, so calling save() is not required unless the instance is later modified.

from myApp.models import MyModel

my_model_1 = MyModel(field1="value1")
my_model_1.save()  # explicit persistance, might need id to be explicitly set to avoid index collision

# implicit persistance, uses autoincrement to determine next id value without collision
my_model_2 = MyModel.objects.create(field1="value2")

Ensure Property Names and Methods Are Unique

Django model classes can have Python properties and methods defined in them. Take care not to define a model field with the same name. This is an example of the problem:

from django.db import models
class MyModel(models.Model): problem_name = models.TextField()
@property def problem_name(self): pass

Creating a Foreign Key Instance

A foreign key relationship means that a given Django model instance can refer to a unique instance of another model. Techopedia has a good definition:

The original table containing the primary key is the parent table (also known as referenced table). This key can be referenced by multiple foreign keys from other tables, known as “child” tables.

When rows in the parent table are deleted, the matching foreign key columns in the child table are also deleted, creating a cascading delete.  – Techopedia

This means that many rows in a child table might refer to the same row in the parent table. Django’s ForeignKey class models many-to-one relationships.

Given a model called Questionnaire:

class Questionnaire(models.Model):
    name = models.TextField()

And given another model called SurveyResult that is linked to it via a foreign key:

class SurveyResult(models.Model):
    name = models.TextField()
    questionnaire = models.ForeignKey(Questionnaire, on_delete=models.CASCADE)

Then when a SurveyResult instance is created, it could be passed an an entire instance of Questionnaire, or just the Questionnaire.id value. Lets look at how each of these would be written:

questionnaire =

survey_result1 = SurveyResult(
    result_json = "{}",
    questionnaire = questionnaire,
    user_id = "x@y.com"

survey_result2 = SurveyResult(
    result_json = "{}",
    questionnaire_id = questionnaire.id,
    user_id = "x@y.com"

The second method shown above uses Django field lookup syntax.

blank=True and null=True

Model fields can have attributes that modify their behavior. Fields that are foreign keys can have two special attributes:

  • null=True – Intuitively, this attribute causes the generated DDL for the SQL table to allow the field to contain NULL.
  • blank=True – This attribute is not intuitive. Applying this attribute to a model field causes the Admin interface to treat the field as being optional, that is, no value need be assigned.

It is common to use both attributes:

my_field = models.OneToOneField(
  to = 'AnotherModel',
  blank = True,
  null = True,
  on_delete = models.CASCADE

Extending Abstract Models