Django
get_or_create
Python
Django Models
Django ORM

How to use get_or_create in Django?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

get_or_create() is a Django ORM convenience method that tries to fetch a row matching given lookup fields and creates it if it does not exist. It is useful when you want one canonical record without writing separate "check then insert" code yourself.

Basic Usage

get_or_create() returns a tuple:

  • the model instance
  • a Boolean telling you whether it was created

Here is the common pattern:

python
1author, created = Author.objects.get_or_create(
2    name="John Doe",
3    defaults={"email": "[email protected]"},
4)
5
6print(author.email)
7print(created)

If an Author with name="John Doe" already exists, Django returns it and created is False. If it does not exist, Django creates it using the lookup fields plus the values in defaults, and created is True.

Understand defaults

The defaults dictionary is used only when a new object must be created. It does not update an existing row.

That means this code:

python
1author, created = Author.objects.get_or_create(
2    name="John Doe",
3    defaults={"email": "[email protected]"},
4)

will not change the email if the author already exists. If you want "find it or update it," the method you probably want is update_or_create(), not get_or_create().

A Practical Example With a Unique Field

get_or_create() works best when the lookup fields uniquely identify the row.

python
1from django.db import models
2
3class Tag(models.Model):
4    name = models.CharField(max_length=100, unique=True)
5
6tag, created = Tag.objects.get_or_create(name="django")
7print(tag.id, created)

This is a good fit because name is unique. The method can reliably return one tag or create exactly one new tag.

Why Uniqueness Matters

If your lookup fields are not unique, get_or_create() can misbehave conceptually or raise exceptions. For example, if multiple rows already match the lookup, Django raises MultipleObjectsReturned.

That means get_or_create() is not magic. It still depends on sensible model design and clear lookup criteria.

In high-concurrency situations, database-level uniqueness is especially important. Two requests can race to create the same row unless the database schema enforces uniqueness for the fields that define identity.

Handling Races and Integrity Errors

Django wraps get_or_create() in a transaction, but true safety still depends on the database constraint. If two concurrent requests try to create the same object and the uniqueness rule lives only in application logic, duplicates are still possible.

So the right pattern is:

  • use get_or_create() for convenience
  • back it with a real unique constraint in the model or database

That combination gives the method a stable identity rule to rely on.

When the code path is especially important, wrap surrounding work in transaction.atomic() so related writes succeed or fail together. get_or_create() handles the lookup-or-insert step, but your broader business operation may still need transactional boundaries around it.

When to Use It

get_or_create() is a good choice when:

  • one row should exist for a given identity
  • you do not want duplicate insert boilerplate
  • you care whether the row was newly created

It is not the right choice when:

  • multiple rows may legitimately match the lookup
  • you want to update existing rows automatically
  • the lookup criteria do not correspond to a real uniqueness rule

Common Pitfalls

  • Assuming defaults updates an existing object. It does not.
  • Using non-unique lookup fields and then being surprised by MultipleObjectsReturned.
  • Relying on get_or_create() without a database uniqueness constraint.
  • Forgetting to inspect the created flag when behavior should differ between existing and newly created records.
  • Using get_or_create() when update_or_create() is the method that actually matches the requirement.

Summary

  • 'get_or_create() returns (object, created) and either fetches an existing row or creates a new one.'
  • 'defaults is applied only when a new object is created.'
  • The method works best when the lookup fields uniquely identify the row.
  • Database-level uniqueness is still important for correctness under concurrency.
  • If you need update behavior too, look at update_or_create() instead.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.