Login

Model with random ID

Author:
[email protected]
Posted:
June 18, 2008
Language:
Python
Version:
.96
Score:
2 (after 2 ratings)

An abstract model base class that gives your models a random base-32 string ID. This can be useful in many ways. Requires a Django version recent enough to support model inheritance.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import random, string

ID_FIELD_LENGTH = 16

class ModelWithRandomID(models.Model):
    id = models.CharField(primary_key=True, max_length=ID_FIELD_LENGTH)
    def save(self):
        if not self.id:
            self.id = random_id(ID_FIELD_LENGTH)
        super(ModelWithRandomID, self).save()
    class Meta:
        abstract = True

# alphabet will become our base-32 character set:
alphabet = string.lowercase + string.digits 
# We must remove 4 characters from alphabet to make it 32 characters long. We want it to be 32
# characters long so that we can use a whole number of random bits to index into it.
for loser in 'l1o0': # Choose to remove ones that might be visually confusing
    i = alphabet.index(loser)
    alphabet = alphabet[:i] + alphabet[i+1:]

def byte_to_base32_chr(byte):
    return alphabet[byte & 31]

def random_id(length):
    # Can easily be converted to use secure random when available
    # see http://www.secureprogramming.com/?action=view&feature=recipes&recipeid=20
    random_bytes = [random.randint(0, 0xFF) for i in range(length)]
    return ''.join(map(byte_to_base32_chr, random_bytes))

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

willhardy (on June 20, 2008):

If you accidently create a new ID that is the same as an existing one, django will overwrite the existing one with your new data. At least, that's how it used to be.

This situation is unlikely for smaller databases but would become more and more likely for bigger ones.

Perhaps it would be better to keep an AutoField primary key, and use another field for your random ID, that isn't the primary key but has unique=True and regenerates the random ID if there are problems saving.

#

willhardy (on June 20, 2008):

Also: UUIDs are in, and python even has a module for it :-)

#

thunderrabbit (on December 28, 2010):

awesome; thank you!

#

Please login first before commenting.