Mike Slinn
Mike Slinn

Django Model Notes

Published 2021-02-12. Last modified 2021-03-29.
Time to read: about 2 minutes.

This article is categorized under Django.

Creating Model Instances

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

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

Python's standard class 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.

Persisting a Django Model Instance
from myApp.models import MyModel

my_model_1 = MyModel(field1="value1")
my_model_1.save()  # explicit persistance

# implicit persistance
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:

myApp/models.py
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:

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

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

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

Then when a SurveyResult instance is created, it must be passed an instance of Questionnaire, not just its ID:

SurveyResult Creation
questionnaire =
  Questionnaire.objects.get(name="questionnaire_1")

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

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:

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

Extending Abstract Models