70👍
My favourite is
import uuid
uuid.uuid4().hex[:6].upper()
If you using django you can set the unique constrain on this field in order to make sure it is unique. https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.Field.unique
21👍
From 3.6 You can use secrets module to generate nice random strings.
https://docs.python.org/3/library/secrets.html#module-secrets
import secrets
print(secrets.token_hex(5))
- [Django]-Disconnect signals for models and reconnect in django
- [Django]-Django Forms with ReactJS
- [Django]-Celery parallel distributed task with multiprocessing
20👍
A more secure and shorter way of doing is using Django’s crypto module.
from django.utils.crypto import get_random_string
code = get_random_string(5)
get_random_string()
function returns a securely generated random string, uses
secrets
module under the hood.
You can also pass allowed_chars
:
from django.utils.crypto import get_random_string
import string
code = get_random_string(5, allowed_chars=string.ascii_uppercase + string.digits)
- [Django]-How to make a PATCH request using DJANGO REST framework
- [Django]-Django Rest Framework: Dynamically return subset of fields
- [Django]-How do I do an OR filter in a Django query?
4👍
Am not sure about any short cryptic ways, but it can be implemented using a simple straight forward function assuming that you save all the generated strings in a set:
import random
def generate(unique):
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
while True:
value = "".join(random.choice(chars) for _ in range(5))
if value not in unique:
unique.add(value)
break
unique = set()
for _ in range(10):
generate(unique)
- [Django]-MySQL vs PostgreSQL? Which should I choose for my Django project?
- [Django]-_() or {% trans %} in Django templates?
- [Django]-Django error: needs to have a value for field "…" before this many-to-many relationship can be used
4👍
If you can afford to lose ‘8’ and ‘9’ in the generated numbers there is a very pythonic solution to getting a random number.
import os
import base64
base64.b32encode(os.urandom(3))[:5].decode('utf-8')
Since you are going for uniqueness then you have a problem since 36 * 36 * 36 * 36 * 36 = 60'466'176
which will definitely result in collisions if you have millions. Since sets are faster than dicts we do…
some_set = set()
def generate():
return base64.b32encode(os.urandom(3))[:5].decode('utf-8')
def generate_unique():
string = generate()
while string in some_set:
string = generate()
some_set.add(string)
return string
However since uniqueness is usually more important I’d recommend generating a unique code for each of the numbers from 0 to 36^5 - 1
like this. We can use a large prime and modulo to make a psuedo-random number like this.
import base64
import math
num = 1
prime_number = 60466181
characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789'
def num_to_code(n: int):
string = ''
hashed = hash_number(n)
for x in range(5):
charnumber = hashed % 36
hashed = math.floor(hashed / 36)
string += characters[charnumber]
return string
def hash_number(n: int, rounds = 20):
if rounds <= 0:
return n
hashed = (n * prime_number) % (36 ** 5)
return hash_number(hashed, rounds - 1)
if __name__ == '__main__':
code = num_to_code(1)
print(code)
Here are the results from generating 0-5, they’ll always generate the same sequence.
0 AAAAA (easily fixable ofc)
1 ZGQR9
2 ON797
3 DUMQ6
4 31384
5 R8IP3
- [Django]-Django get the static files URL in view
- [Django]-How can I change the default Django date template format?
- [Django]-Control the size TextArea widget look in django admin
3👍
If you have a way of associating each user to a unique ID (for example Primary Key
in Django or Flask). You can do something like this:
Note: This does not generate a fixed length.
We will pad the user_id
to the right to make the generated length a bit static
import os
import base64
user_id = 1
#pad the string
number_generate = str(user_id).rjust(5,"0")
base64.b32encode(bytes(number_generate, 'utf-8')).decode('utf-8').replace('=','')
- [Django]-PyCharm Not Properly Recognizing Requirements – Python, Django
- [Django]-Django order_by query set, ascending and descending
- [Django]-Sorting related items in a Django template
1👍
size = 5
''.join(random.choice(string.letters[26:] + string.digits) for in range(size))
this will generate some short code, but they can be duplicated. so check if they are unique in your database before saving.
def generate(size=5):
code = ''.join(random.choice(string.letters[26:] + string.digits) for in range(size))
if check_if_duplicate(code):
return generate(size=5)
return code
or using django unique constrain, and handle exceptions.
- [Django]-Django REST Framework POST nested objects
- [Django]-Django Forms with ReactJS
- [Django]-When to use Django get_absolute_url() method?
1👍
There is a function in django that does what you’re looking for (credits to this answer):
Django provides the function
get_random_string()
which will satisfy
the alphanumeric string generation requirement. You don’t need any
extra package because it’s in thedjango.utils.crypto
module.>>> from django.utils.crypto import get_random_string >>> unique_id = get_random_string(length=32) >>> unique_id u'rRXVe68NO7m3mHoBS488KdHaqQPD6Ofv'
You can also vary the set of characters with
allowed_chars
:>>> short_genome = get_random_string(length=32, allowed_chars='ACTG') >>> short_genome u'CCCAAAAGTACGTCCGGCATTTGTCCACCCCT'
- [Django]-How to get a list of all users with a specific permission group in Django
- [Django]-Django Migrations Add Field with Default as Function of Model
- [Django]-Django URLs TypeError: view must be a callable or a list/tuple in the case of include()
1👍
I have a unique field, named ‘systemCode‘ within a lot of my models. And I am generating this manually, but also sometimes it can take value from user input, so I have to check this value before saving and if it matches , regenerating this value as a unique value.
And this is how I generate unique strings at this scenario :
This is my standard class Model :
class ClassOne(models.Model):
name = models.CharField(max_length=100)
systemCode = models.CharField(max_length=25, blank=True, null=True, unique=True)
....
I am using save() method to generate and check this systemCode is unique :
def save(self, *args, **kwargs):
systemCode = self.systemCode
if not systemCode:
systemCode = uuid.uuid4().hex[:6].upper()
while ClassOne.objects.filter(systemCode=systemCode).exclude(pk=self.pk).exists():
systemCode = uuid.uuid4().hex[:6].upper()
self.systemCode = systemCode
super(ClassOne, self).save(*args, **kwargs)
But I have same systemCode field in all my Models. So I am using a function to generate value.
So, this is how to generate unique value for all models using saveSystemCode() function :
import uuid
def saveSystemCode(inClass, inCode, inPK, prefix):
systemCode = inCode
if not systemCode:
systemCode = uuid.uuid4().hex[:6].upper()
while inClass.objects.filter(systemCode=systemCode).exclude(pk=inPK).exists():
systemCode = uuid.uuid4().hex[:6].upper()
return systemCode
class ClassOne(models.Model):
name = models.CharField(max_length=100)
systemCode = models.CharField(max_length=25, blank=True, null=True, unique=True)
....
def save(self, *args, **kwargs):
self.systemCode = saveSystemCode(ClassOne, self.systemCode, self.pk, 'one_')
super(ClassOne, self).save(*args, **kwargs)
class ClassTwo(models.Model):
name = models.CharField(max_length=100)
systemCode = models.CharField(max_length=25, blank=True, null=True, unique=True)
....
def save(self, *args, **kwargs):
self.systemCode = saveSystemCode(ClassTwo, self.systemCode, self.pk, 'two_')
super(ClassTwo, self).save(*args, **kwargs)
class ClassThree(models.Model):
name = models.CharField(max_length=100)
systemCode = models.CharField(max_length=25, blank=True, null=True, unique=True)
....
def save(self, *args, **kwargs):
self.systemCode = saveSystemCode(ClassThree, self.systemCode, self.pk, 'three_')
super(ClassThree, self).save(*args, **kwargs)
while loop in the ‘saveSystemCode‘ function is preventing to save same value again.
- [Django]-Make clicked tab active in Bootstrap
- [Django]-Django Reverse Accessor Clashes
- [Django]-Django: How to get current user in admin forms?
- [Django]-Django – Website Home Page
- [Django]-Can I make list_filter in django admin to only show referenced ForeignKeys?
- [Django]-How do you detect a new instance of the model in Django's model.save()
1👍
Here a solution to gen codes of lenght 5 or any on a file:
import shortuuid as su
n = int(input("# codes to gen: "))
l = int(input("code lenght: "))
shou = su.ShortUUID(alphabet="QWERTYUIOPASDFGHJKLZXCVBNM0123456789")
codes = set()
LEN_CNT = 0
with open('file.txt', 'w') as file:
while len(codes) < n:
cd = shou.random(length=l)
codes.add(cd)
if len(codes) > LEN_CNT:
LEN_CNT = len(codes)
file.write(f"{cd}\n")
(shortuuid sometimes gen duplicated codes, so I use a set to deal with that)
- [Django]-Iterating over related objects in Django: loop over query set or use one-liner select_related (or prefetch_related)
- [Django]-Django: implementing JOIN using Django ORM?
- [Django]-Django Admin – Overriding the widget of a custom form field
0👍
As the time of writing this answer, there is an actively maintained package that generates short UUIDs:
https://github.com/skorokithakis/shortuuid
For Django support, have a look here:
- [Django]-Why does django ORM's `save` method not return the saved object?
- [Django]-Django's ManyToMany Relationship with Additional Fields
- [Django]-How do I install an old version of Django on virtualenv?