Unique gift/coupon code generation with Django
The problem: Creating human friendly unique gift codes for an e-commerce Django app.
In this tutorial I’ll share an easy approach for generating gift/coupon codes that are short and simple while maintaining uniqueness. The unique codes for this tutorial will look like these: BSKWM432, HTSQW150, …

The problem, why don’t we just use the built in Django UUIDField?
The issue with using the Django built in UUIDField is that although it provides near perfect uniqueness (virtually guaranteeing no collisions) — it’s not human friendly. If you use the recommended uuid.uuid4() as the default for your Django model field you’re left with gift/coupon codes that look like this:
$python
>>> import uuid
>>> my_unique_code = uuid.uuid4()
>>> print(my_unique_code)
48a6ec8b-4929-426e-a1c3-9381b2e603d3Which, unless you have a very security sensitive e-commerce site, is serious overkill and will not provide your customer with a positive experience if they have to manually key in the gift/coupon code.
The solution, use the Postgres primary key (ID Field) and inject it into a randomly generated string.
If we’re able to access the Postgres primary key (ID Field) in our Django app then we can append or mix-in (in a consistent and predetermined way) the unique primary key field with a randomly created string to ensure that all our strings remain unique — right?
We know that the primary key (ID field) will always be unique:
1,2,3, … , N
Then if we always add the primary key to the end/start/middle of the random string it’ll look like this:
{random_str}1, {random_str}2, {random_ str}3, … , {random_str}N
Ah ha! Unique codes! Ok, so how do we achieve this in our Django app?
The only tricky part about making our solution work with Django is that we do not have access to the primary key (ID field) until after the model instance has been saved to the database. This means we need to first save the model instance with a default value without breaking the unique constraint of the model before we are able to circle back and create our unique code. Luckily Django helps us do that by setting:
blank=True, null=True, unique=TrueAdd any fields that are relevant for your coupon or gift class (is_redeemed, credit, discount_rate, etc.) and migrate your model changes to the DB.
$python manage.py makemigrations
$python manage.py migrateNext, we need to create our unique gift/coupon codes after the model instance has been saved to the database. As we will only have access to the primary key (ID field) after the instance has been created in our database. Django signals to the rescue! We’ll make a post_create function which first checks that we have access to the models primary key (ID field). Once we know we have the ID and the instance has been created, we use the secrets module to generate a random string and append the ID to the back of the random string to finish creating our unique code. Finally, re-save the model instance now that it includes the unique code.
Lastly, don’t forget to connect the post_create method to the post_save signal sent from the UniqueCodes model class. Essentially, causing the app to hit the post_create method every time a UniqueCodes model instance is saved. I’ve included the full code snippet for models.py below:
Consideration
When you are designing your gift/coupon code solution consider how security sensitive your implementation needs to be. Be aware that the longer the code the less susceptible to a brute force attack it will be. Consider lengthening your gift/coupon code or devising a way to sprinkle the numeric digits throughout if you need more security.