How to Use UUID as a Primary ID in Django Models
Tags: python, django, uuid
Published: 2020-03-31 13:29:53

---
title: How to Use UUID as a Primary ID in Django Models
published: true
date: 2020-01-02 00:00:00 UTC
tags: python, django, uuid
canonical_url: https://tech.serhatteker.com/post/2020-01/uuid-primary-key/
---

# Intro
In Django whenever we create any new model, there is an `ID`-or `PK`, model field attached to it. The `ID` field’s data type is `integer` by default.

To make this integer id field `UUID`, we can use `UUIDField` model field, which was added in `Django 1.8`.

# UUID
**A universally unique identifier (UUID)** is a 128-bit number used to identify information in computer systems.  They are commonly represented as *32 hexadecimal* characters separated by four hyphens.

There are 5 versions of UUID:
1. Version 1: date-time and MAC address
2. Version 2: date-time and MAC address, DCE security version
3. Versions 3: namespace name-based
4. Version 4: random
5. Version 5: namespace name-based

For more details go to : [WIKI UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions)

## Which UUID Version To Choose
There are two different ways of generating an UUID.

__1.__ If you just need a "unique ID", you want a version 1 or version 4:

* __Version 1__: This generates a unique ID based on a network card MAC address and a timer. These IDs are easy to predict (given one, I might be able to guess another one) and can be traced back to your network card. It's not recommended to create these.
* __Version 4__: These are generated from random (or pseudo-random) numbers. If you just need to generate a UUID, this is generally what you want.

__2.__ If you need to always generate the "same" or "reproducible" UUID" from a given name, you want a version 3 or version 5. It means that if you feed that algorith with the same input, it will generate the same output.

* __Version 3__: This generates a unique ID from an MD5 hash of a namespace and name. If you need backwards compatibility (with another system that generates UUIDs from names), use this.

* __Version 5__: This generates a unique ID from an SHA-1 hash of a namespace and name. This is the preferred version.

## Collision
The probability to find a duplicate within 103 trillion version-4 UUIDs is one in a billion.

It means that if you produce "every second" an UUID for `3,266,108` year, your collision chance is `.000000001`.

# Django Model
As we mentioned earlier, we will use `UUIDField` model field and "version 4" UUID as the default value for the field.

So let's create a model:

```python
#src/myapp/models.py
import uuid

from django.db import models
from django.utils.translation import ugettext_lazy as _


class Event(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("Name of Event"), blank=True, max_length=255)
```

Run migrations to activate the model:

```bash
$ python manage.py makemigrations
$ python manage.py migrate
```

## Test the Model
In the root directory of your project, run to activate python shell:

```bash
$ python manage.py shell
```

Type below codes:

```python
# import the model
>>> from src.myapp.models import Event
# create and save an event
>>> event = Event(name="FullMoon")
>>> event.save()
# get al objects from database
>>> obj = Event.objects.all()
# get the id of the one that we just created
>>> obj.first().id
UUID('35bfdc19-6ec2-4c41-b0a3-b50d07b30043')
>>> obj.first().pk
UUID('35bfdc19-6ec2-4c41-b0a3-b50d07b30043')
```

As you can see, our new model uses UUID as an ID. And our UUID is
`35bfdc19-6ec2-4c41-b0a3-b50d07b30043`.

All done!

---

References:

* [Which UUID](https://stackoverflow.com/a/20342413)
* [UUID Collision](https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions)