Django shortcuts – get_or_create and update_or_create

Django shortcuts, get_or_create(), and update_or_create() methods make our web application development even faster. Django implemented these methods due to easier readability and non-repetitiveness of the code.

What is the get_or_create() method in Django?
The get_or_create() method is used to get an existing object from the database or create it if it doesn’t exist. The get _or_create() method returns a tuple. A first element is an object, and the second one boolean value (created is True, not created is False).

What is the update_or_create() method in Django?
The update_or_create() method is used to update an object from the database if the object exists. If not, the object is created from provided parameters. The update_or_create() method returns tuple. A first element is an object, a second one boolean value (created is True, updated is False).

Before we dive into examples, we should define our models.

from django.db import models

class Author(models.Model):
    first_name = models.CharField(max_length=512)
    last_name = models.CharField(max_length=512)

class Book(models.Model):
    title = models.CharField(max_length=512)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

Django get_or_create() method

The get_or_create() method is the model Manager method that can receive keyword arguments that represent model fields.

get_or_create(defaults=None, **kwargs)

  • defaults – if an object doesn’t exist, defaults define object fields that are saved into the database.
  • kwargs – defines fields used in the lookup for the get method, and if defaults are not defined, the same fields are used to create the method.
>>> Author.objects.get_or_create(first_name="William", last_name="Shakespeare")
(<Author: Author object (1)>, True)

>>> Author.objects.get_or_create(first_name="William", last_name="Shakespeare")
(<Author: Author object (1)>, False)

We get two same commands but two different outputs. First, when we called get_or_create() method ‘William Shakespeare’ was not in the database, get_or_create() created Author and returned True in tuple providing us information that Author was created. The second time we called the get_or_create() method on the same arguments. We were provided with the Author created previously. The created flag is False, providing us information that Author was not created (only fetched from the database).

The authors table in the database looks like this:

WARNING - If the field that doesn't exist is provided, we get FieldError.

Now, we can look at the defaults argument that is provided alongside kwargs. As already mentioned, defaults don’t interfere while getting an object from the database – but if an object with given arguments doesn’t exist, defaults argument ‘overrides’ arguments and creates an object with given parameters. So let’s take a look at the following example.

>>> Author.objects.get_or_create(first_name="William", last_name="Shakespeare", defaults={"first_name": "Miguel", "last_name": "de Cervantes"})
(<Author: Author object (1)>, False)

As we can see, ‘William Shakespeare’ is already in the database, and no new object is created even though we defined defaults.

What happens if author doesn’t exist?

>>> Author.objects.get_or_create(first_name="Agatha", last_name="Christie", defaults={"first_name": "Miguel", "last_name": "de Cervantes"})
(<Author: Author object (2)>, True)

‘Agatha Christie’ was not yet created when calling the get_or_create() method in Django. We can see now that the Author object is created. Let’s check the database.

2Miguelde Cervantes

There is no mention of ‘Agatha Christie’; instead, we have ‘Miguel de Cervantes’ Author defined in the defaults argument. So, defaults define object fields when no object is found from the arguments we provided.

Django update_or_create() method

As the get_or_create() method, update_or_create() is also the model Manager method, but with a slightly different purpose. The update_or_create() updates object if found; if not, it’s created. The return value is a tuple with two values, object and created boolean flag.

update_or_create(defaults=None, **kwargs)

  • defaults – Defines values of fields that should be updated (or created)
  • kwargs – Defines fields used in lookup for update method, and if defaults is not defined, same fields are used for creating object.

Let’s take a look at the following example:

>>> Author.objects.update_or_create(first_name="Miguel", defaults={"first_name": "Agatha", "last_name": "Christie"})
(<Author: Author object (2)>, False)

This example looked for an object with first_name ‘Miguel’, as we have this Author in our database Django proceeds to iterate over defaults argument key-value pairs and updates given object.

Our database after this change looks like this:

WARNING - If defaults is not defined, create method uses provided keyword arguments as fields!
>>> Author.objects.update_or_create(first_name="William", last_name="Shakespeare")
(<Author: Author object (3)>, True)

As seen in the example above, we can use update_or_create() in Django to create new objects without using the defaults argument. However, this doesn’t use its purpose because no object will be updated without defaults.