How to fix TypeError: __init__() missing 1 required positional argument: 'on_delete'

When creating Django models for your database, you might see the following error:

TypeError: __init__() missing 1 required positional argument: 'on_delete'

This error occurs when you skip the on_delete argument when defining your model’s relationship with another model.

Let’s see an example that causes this error and how to fix it.

How to reproduce this error

Let’s say you need to create two related Django models between pet owners and their pets.

First, you create a model for the pet owners as follows:

from django.db import models

class PetOwner(models.Model):
    name = models.CharField(max_length=200)
    age = models.IntegerField(default=0)

Next, you create another model named Pet that has a ForeignKey constraint to the PetOwner model:

class Pet(models.Model):
    owner = models.ForeignKey(PetOwner)
    pet_name = models.CharField(max_length=200)
    pet_species = models.CharField(max_length=200)

When you run the makemigrations command to generate the models, you get a long error trace that ends as follows:

Traceback (most recent call last):
    owner = models.ForeignKey(PetOwner)
TypeError: ForeignKey.__init__() missing 1 required 
positional argument: 'on_delete'

This error occurs because the ForeignKey class requires you to pass the on_delete argument when you instantiate an object from it.

The on_delete argument is used to let Django knows what to do with the model data when you delete data from the model it was referencing.

In this case, you need to specify what to do with Pet data when PetOwner data got removed.

How to fix this error

To resolve this error, you need to pass an on_delete argument with one of the following values:

  • CASCADE
  • RESTRICT
  • PROTECT
  • SET_DEFAULT
  • SET_NULL
  • SET()
  • DO_NOTHING

The most common option is CASCADE which deletes all rows from Pet that reference the row in PetOwner table.

But you can also use DO_NOTHING as follows:

class Pet(models.Model):
    owner = models.ForeignKey(PetOwner, on_delete=models.DO_NOTHING)
    pet_name = models.CharField(max_length=200)
    pet_species = models.CharField(max_length=200)

Once you add the on_delete argument to all models that have the ForeignKey constraint, you should be able to run makemigrations without seeing this error.

You can look at Django ForeignKey documentation for more information about what each option does.

Now you’ve learned how to resolve the error missing 1 required positional argument: 'on_delete' when developing Django applications.

I hope this tutorial helps. Until next time! 👋

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.