Как установить вызываемую функцию в атрибут AutoField по умолчанию? - PullRequest
1 голос
/ 28 июня 2019

Я пытаюсь перезаписать ПК моих моделей, чтобы использовать генератор случайных чисел.

Вот поле модели:

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

и генератор ключей:

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

Итак, я бы хотел, чтобы автополе выполняло функцию genkey в максимально возможной степени, пока не получит неиспользуемый ключ. Есть ли атрибут, который я не нашел, или мне нужно кодировать его в генераторе (получая все использованные ключи)?

Моя главная цель - сделать генератор как можно более универсальным, а не определять собственный генератор для каждой модели.

Ответы [ 2 ]

0 голосов
/ 01 июля 2019

Проведя некоторые исследования и тесты, я в итоге создал класс.

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

0 голосов
/ 28 июня 2019

An AutoField [Django-doc] , как сказано в документации:

IntegerField, который автоматически увеличиваетсясогласно имеющимся идентификаторам .Вам обычно не нужно использовать это напрямую;поле первичного ключа будет автоматически добавлено в вашу модель, если вы не укажете иное.

Таким образом, это IntegerField [Django-doc] , и поэтому мы можем просто использовать IntegerField вместо этого, llike:

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

Так что указание значения по умолчанию для AutoField немного противоречит тому, что делает AutoField.Если вы сделаете IntegerField с editable=False [Django-doc] , чтобы гарантировать, что, по крайней мере по умолчанию, он не будет включен в ModelForm.По сути, это то, что делает первичный ключ.

...