Getting duplicate get_random_string(length=36) for default model field pk

With a model primary key defined as follows, somehow duplicate ids are being generated, resulting in an exception:

our_id = models.CharField(max_length=Constants.MAX_KEY_LENGTH, default=get_random_string(length=Constants.MAX_KEY_LENGTH), primary_key=True)

The model object is created in usual way (has one or more foreign keys that need to be specified), in our Apache MPM environment, where I believe each Python process is single threaded:

our_obj = OurModel(our_foreign=our_other)
our_obj.save()

To sidestep the issue we’re currently specifying the id in the model creation statement, also calling get_random_string, but I really can’t see what the difference is here, where won’t the Django library, in response to the default field, just call get_random_string in the same process / thread?

Placing this function call in the default means that when the module is imported, the function will be called, and that value will be assigned as the default. The expression (get_random_string()) gets evaluated once.

If you want a “variable default”, you need to specify a callable, not actually call the function.
e.g. default = get_random_string

Of course! Thanks :+1:. Am I correct in thinking that there isn’t any way to pass any parameters, but actually, it would be better if we defined a local (in models.py) function that calls get_random_string with our maximum key length (several model fields are defined in the same way).

I’m not aware of a way to do it directly. I’ve only done it by having the callable call the “real” function with the appropriate parameters.

e.g.

def get_random_for_x():
    return get_random_string(length=50)

def get_random_for_y():
    return get_random_string(length=64)

def get_random_for_z():
    return get_random_string(length=100)

and then the models use default=get_random_for_x (or y, or z).

Indeed, where we have a whole bunch of pks, which all have the same key length, so a single function will work very nicely for us. Thanks again.