Dran Dev
Dran Dev

Reputation: 519

Generating random string (for unique code) keeps returning the same random string

I have a Test model where each test can be identified by a unique randomly-generated string:

from django.utils.crypto import get_random_string

class Test(models.Model):
    code_length = 7
    code = models.CharField(max_length=code_length, editable=False, default=generate_id(code_length))
    name = models.CharField(max_length=100, default=None)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return "Code: {} | Username: {} | Test: {}".format(self.code, self.user.username, self.name)

def generate_id(length):
    return get_random_string(length)

Tbh, it was working good before. It started to "bugged-out" after I updated my Django from Django 1.x to Django 3.x and I also cleared all the records of the Test model in django-admin (I want to have a fresh and clean database for testing). Right now, whenever I try and create a new Test, it's code is literally the same with all other new Tests that I create:

enter image description here

I think I haven't done anything to it other than those two changes I made. Any ideas? Thanks a lot!

Upvotes: 2

Views: 1441

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477180

You should not call the function, since then the default will take the result of the funcation call.

You thus construct a function:

from django.utils.crypto import get_random_string

CODE_LENGTH = 7

def generate_id_length():
    return get_random_string(CODE_LENGTH)

class Test(models.Model):
    code = models.CharField(
        max_length=CODE_LENGTH,
        editable=False,
        #          no parenthesis ↓
        default=generate_id_length
    )

if you do not want to move CODE_LENGTH outside the Test class, you can use:

from django.utils.crypto import get_random_string

def generate_id_length():
    return get_random_string(Test.code_length)

class Test(models.Model):
    code_length = 7
    code = models.CharField(
        max_length=CODE_LENGTH,
        editable=False,
        #          no parenthesis ↓
        default=generate_id_length
    )

Upvotes: 5

Related Questions