Created
July 10, 2019 22:46
-
-
Save tveastman/4114f1bf7777c1a252777f4305cdb1f0 to your computer and use it in GitHub Desktop.
Here's an example of how I've used HashIds to create a non-numeric identifier for Django models based on their `id`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hashids | |
class HashidsMixin(object): | |
"""Add a unique 'identifier' mapped from the 'id' field of a django model.""" | |
# Updating this salt would change every identifier for all instances of | |
# every model. This is probably a bad idea, so it should probably never | |
# ever change. It's not used for security -- just a little bit of extra | |
# obfuscation to the numbering. | |
__HASHIDS_SALT = "20OGoZ5KsC" | |
@classmethod | |
def __hashids(cls): | |
if not hasattr(cls, "__hashid_instance"): | |
cls.__hashids_instance = hashids.Hashids( | |
# We stick to the plain alphabet because we can't risk | |
# having identifiers that start with numerals (I think | |
# It'd break somebody's rules somewhere). | |
alphabet="abcdefghijklmnopqrstuvwxyz", | |
# Tagging the class name onto the salt guarantees that | |
# the counting system is different for each class. | |
salt=cls.__HASHIDS_SALT + cls.__name__, | |
# Four seems reasonable, it'll be a long time before it | |
# jumps to five digits, and the identifiers look 'meaty' | |
# which adds to their inscrutability | |
min_length=4, | |
) | |
return cls.__hashids_instance | |
@classmethod | |
def decode_identifier(cls, string): | |
"""Decode the integer from an identifier. | |
>>> app.models.MyModel.decode_identifier('asnf') | |
1 | |
Although hashids lets you encode multiple ids, we always assume | |
we're only receiving exactly one, and anything else will be | |
ignored. | |
""" | |
ids = cls.__hashids().decode(string) | |
return None if len(ids) != 1 else ids[0] | |
@property | |
def identifier(self): | |
return self.__hashids().encode(self.id) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment