Search code examples
djangodjango-modelsparametersdefault

How to set a callable function to AutoField default attribute?


I'm trying to overwrite the pk of my models to use a random generator.

Here's the model field:

pk = models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', default=genkey)

and the keygenerator:

def genkey():
    return random.randrange(1,142857)

So, I would like to make the autofield to execute the genkey function as much as possible until it gets a non-used key. Is there an attribute that I didn't find or do I need to code it in the generator (by getting all the used keys) ?

My main goal is to make a generator as generic as possible, not define a custom generator for each model.


Solution

  • After making some research and tests, I ended up creating a class.

    class RandomIDKey(models.Model):
        id = models.IntegerField(
            auto_created=True,
            primary_key=True,
            serialize=False,
            verbose_name='ID',
            unique=True,
            db_index=True,
            editable=False
        )
    
        def save(self, *args, **kwargs):
            if not self.id:
                self.id = genkey(type(self))
            super().save(*args, **kwargs)
    
        class Meta:
            abstract = True
    

    with a public function:

    def genkey(model):
        generated_key = random.randrange(1, 2147483648)
        if model.objects.filter(pk=generated_key).exists():
            generated_key = genkey(model)
        return generated_key
    

    Using an AutoField is a bad idea since the field is not auto-generated by the database, hence the IntegerField