G is for get_or_create - Python A to Z
Code in this blog post was written with versions: Python: 3.14
Python A-Z is a blog series about Python. Each day, I share insights, ideas and examples for different parts of Python development that match with the letter of the day. Blaugust is an annual blogging festival in August where the goal is to write a blog post every day of the month.
Let’s take our first journey into the wonders of Django, my favourite web backend. One of the reasons I love it is its ORM which we’ll talk a bit more when we reach the midway of the month and letter O.
Today, I want to show my appreciation for one of the methods in QuerySet: get_or_create which allows you to create new items in the database but if one already exists, it returns it instead.
from .models import Bread, BreadType
# (here, Bread.bread_type is a ForeignKey to BreadType)
breads_input = [{ 'id': 1, 'breadType': 'bun' } , ... ]
for bread_data in breads:
bread_type, type_created = BreadType.objects.get_or_create(type=bread_data['breadType'])
bread, bread_created = Bread.objects.get_or_create(id=bread_data['id'], bread_type=bread_type)
Here we process through some list of dictionaries (imagine it’s read from a JSON file or queried from a REST API). First, we try to create a new BreadType but if one already exists, we return a reference to it rather than creating a new one every time. Then we create a bread, using the previous reference. If we’d already have that specific bread inputted (maybe we ran the command twice), we want to get the existing one rather than creating new ones every time.
I especially love using it in my data entry scripts / custom Django commands. Many of my applications operate on a model where I periodically input new data through these commands: for example in Pokémon TCG app, when a new set is released.
Pokémon TCG is a great example. Right now, when my script reads in data for
new cards, there are 13 such relationships between my Card model and other
models. The codebase looks so much neater and easier to follow thanks to
get_or_create.
Edit later on Aug 8th: I rewrote the entire post to better explain what get_or_create does.
If something above resonated with you, let's start a discussion about it! Email me at juhis@hamatti.org and share your thoughts. This year, I want to have more deeper discussions with people from around the world and I'd love if you'd be part of that.