如何将可调用函数设置为AutoField默认属性?

时间:2019-06-28 10:22:37

标签: django django-models parameters default

我正在尝试覆盖模型的pk以使用随机生成器。

这是模型字段:

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

和密钥生成器:

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

因此,我想让自动域尽可能执行genkey函数,直到获得未使用的键为止。有没有我找不到的属性,还是需要在生成器中编码(通过获取所有已使用的键)?

我的主要目标是使生成器尽可能通用,而不是为每个模型定义自定义生成器。

2 个答案:

答案 0 :(得分:0)

AutoField [Django-doc]就像文档中所说的那样:

  

一个IntegerField,它会根据可用的ID自动递增。您通常不需要直接使用它;如果没有另外指定,主键字段将自动添加到模型中。

因此它是IntegerField [Django-doc],因此我们可以简单地使用IntegerField来代替llike:

class SomeModel(models.Model):
    pk = models.IntegerField(editable=False, auto_created=True, primary_key=True, verbose_name='ID', default=genkey)
    # ...

因此,在AutoField上指定默认值与AutoField的操作有点矛盾。如果您用editable=False [Django-doc]制作一个IntegerField,则至少在默认情况下,确保它不会包含在ModelForm中。本质上,这就是主键的作用。

答案 1 :(得分:0)

在进行了一些研究和测试之后,我最终创建了一个类。

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

具有公共功能:

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

使用AutoField是一个坏主意,因为该字段不是由数据库自动生成的,因此IntegerField