I mentioned an error called: typeerror: __init__() missing 1 required positional argument: 'on_delete'
in my post about the significance of the Django on_delete argument and its 7 options. But that was just mentioned, I did not really explain why the on_delete error happened, when does it happen, and most importantly, how to fix it when it happens. So this post is going to talk about all the things that relate to fixing the typeerror: __init__() missing 1 required positional argument: 'on_delete'
.
Let’s get started.
Table of Contents
- When Does the typeerror: __init__() missing 1 required positional argument: ‘on_delete’ happen.
- How Does the typeerror: __init__() missing 1 required positional argument: ‘on_delete’ look like
- Why Does Django Throw the typeerror: __init__() missing 1 required positional argument: ‘on_delete’
- How To Fix typeerror: __init__() missing 1 required positional argument: ‘on_delete’
When Does the typeerror: __init__() missing 1 required positional argument: ‘on_delete’ happen.
As the name itself can tell, the typeerror: __init__() missing 1 required positional argument: 'on_delete'
happens when you omit the required positional argument called on_delete in a field that is referencing another object. This reference can be in a relationship of a Foreign key (Django’s Many-to-One relationship), Many-to-Many relationship, and One-to-One relationship.
class Album(models.Model):
name = models.CharField(max_length=30)
artist = models.ForeignKey(Artist, )
👆# Here's where you're supposed to add on_delete
How Does the typeerror: __init__() missing 1 required positional argument: ‘on_delete’ look like
In the console, the error is usually very long. But the last line will summarize all the above mess. Like below:
TypeError: ForeignKey.__init__() missing 1 required positional argument: 'on_delete
This is basically telling you the error.
Why Does Django Throw the typeerror: __init__() missing 1 required positional argument: ‘on_delete’
Django throws the typeerror: __init__() missing 1 required positional argument: ‘on_delete’ because it does not want your database to be messed up. It wants something to happen to objects that are referencing other objects when those referenced objects get deleted. That’s why you are supposed to include the on_delete argument to all foreign keys and that’s why it offers you 7 options for the on_delete argument.
How To Fix typeerror: __init__() missing 1 required positional argument: ‘on_delete’
Here is how to fix the Django error: typeerror: __init__() missing 1 required positional argument: ‘on_delete’
- Identify the model with the field that is referencing other objects but without the on_delete argument.
- Determine the appropriate on_delete option and add it to the field.
Let’s get into the detail about each step:
1. Identify the model with the field that is referencing other objects but without the on_delete argument.
The good news is, you do not have to look for this model and field manually. It’s all in the error itself.
File "Path", line 11, in Album
artist = models.ForeignKey(Artist)
TypeError: ForeignKey.__init__() missing 1 required positional argument: 'on_delete'
The Path
is the absolute path to the file in your Django project that has the model that is causing the problem. In Visual Studio Code, you can press CTRL on the keyboard and click the path and you will be taken to the file. These kinds of errors usually happen in the models.py
files.
line 11
in my case is the line where the error has originated.
Album
, in my case, is the name of the model to which the field that is referencing another object belongs.
Below is the very line that has the error on it. Looking at the line: artist = models.ForeignKey(Artist)
, you can tell that artist
is referencing an Artist
object in Many to One relationship(ForeignKey), but there is something that is missing, and that is the on_delete
argument next to Artist. Once you have figured out the line that is causing the error, it’s time to add the argument with an appropriate option.
2. Determine the appropriate on_delete option and add it to the field.
Django provides you with 7 options for the on_delete argument which are CASCADE, RESTRICT, PROTECT, SET_DEFAULT, SET_NULL, SET(), and DO_NOTHING. CASCADE is the most popular option; what it does is deletes the objects that are referencing an object when that object gets deleted. So if that is what you want to happen to your object, then it will be fine. Check my post on Django on_delete to learn more about each of these options.
Your Model should now look like this:
class Album(models.Model):
name = models.CharField(max_length=30)
artist = models.ForeignKey(Artist, on_delete = models.CASCADE)
And you will be done!
Most of the time, there is no need to make migrations or migrate the database.
That’s how we solve the typeerror: __init__() missing 1 required positional argument: ‘on_delete’ in Django. Peace!