Using a UUID as a primary key in Django models (generic relations impact) Using a UUID as a primary key in Django models (generic relations impact) django django

Using a UUID as a primary key in Django models (generic relations impact)


As seen in the documentation, from Django 1.8 there is a built in UUID field. The performance differences when using a UUID vs integer are negligible.

import uuidfrom django.db import modelsclass MyUUIDModel(models.Model):    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

You can also check this answer for more information.


A UUID primary key will cause problems not only with generic relations, but with efficiency in general: every foreign key will be significantly more expensive—both to store, and to join on—than a machine word.

However, nothing requires the UUID to be the primary key: just make it a secondary key, by supplementing your model with a uuid field with unique=True. Use the implicit primary key as normal (internal to your system), and use the UUID as your external identifier.


I ran into a similar situation and found out in the official Django documentation, that the object_id doesn't have to be of the same type as the primary_key of the related model. For example, if you want your generic relationship to be valid for both IntegerField and CharField id's, just set your object_id to be a CharField. Since integers can coerce into strings it'll be fine. Same goes for UUIDField.

Example:

class Vote(models.Model):    user         = models.ForeignKey(User)    content_type = models.ForeignKey(ContentType)    object_id    = models.CharField(max_length=50) # <<-- This line was modified     object       = generic.GenericForeignKey('content_type', 'object_id')    vote         = models.SmallIntegerField(choices=SCORES)