Generating a non-sequential ID/PK for a Django Model

There is built-in Django way to achieve what you want. Add a field to the model of “custom page” with primary_key=True and default= name of key generation function, like this:

class CustomPage(models.Model):
    ...
    mykey = models.CharField(max_length=6, primary_key=True, default=pkgen)
    ...

Now, for every model instance page, page.pk becomes an alias for page.mykey, which is being auto-assigned with the string returned by your function pkgen() at the moment of creation of that instance.
Fast&dirty implementation:

def pkgen():
    from base64 import b32encode
    from hashlib import sha1
    from random import random
    rude = ('lol',)
    bad_pk = True
    while bad_pk:
        pk = b32encode(sha1(str(random())).digest()).lower()[:6]
        bad_pk = False
        for rw in rude:
            if pk.find(rw) >= 0: bad_pk = True
    return pk

The probability of two pages getting identical primary keys is very low (assuming random() is random enough), and there are no concurrency issues. And, of couse, this method is easilly extensible by slicing more chars from encoded string.

Leave a Comment

tech