Как сделать в Django идентификатор по умолчанию (pk) случайным и большим по длине

Я создаю модель Profile, в которой я получаю id по умолчанию с именем id, но проблема в том, что она генерирует id от 0 и далее, например 1, 2,. Я хочу получить случайный идентификатор, который также должен быть длиннее, например 343347 и т.д.

Вы можете использовать следующий код. Но при этом возможно дублирование номера и ошибка.

import random

def big_random():
    return random.randint(1000000, 9999999)


class Foo(models.Model):
    id = models.IntegerField(default=big_random, primary_key=True)
    bar = models.CharField(max_length=30)

Я предлагаю использовать uuid в качестве pk:

import uuid

class Foo(models.Model):
    id = models.IntegerField(default=uuid.uuid4, primary_key=True)
    bar = models.CharField(max_length=30)

Используйте UUIDField. Скопировано из документа:

Поле для хранения универсально уникальных идентификаторов. Использует UUID из Python класс. При использовании в PostgreSQL хранится в типе данных uuid, в противном случае в char(32).

Универсально уникальные идентификаторы являются хорошей альтернативой AutoField для первичного_ключа. База данных не будет генерировать UUID за вас, поэтому рекомендуется рекомендуется использовать значение по умолчанию:

import uuid from django.db import models

class MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # other fields

Обратите внимание, что по умолчанию передается вызываемый объект (скобки опущены), а не экземпляр UUID. default, а не экземпляр UUID.

Если требуется уникальное 32-битное целое число, которое можно использовать вместо pk в URL, можно использовать обратимую функцию сопоставления 1 к 1 в пределах этого домена. Это не будет безопасным, но не позволит людям, не имеющим доступа к вашему исходному коду, "ловить" следующий или предыдущий pk.

Используя CBVs, вы с одной стороны декодируете "pk", который не является pk, например, в подклассе метода get_object, а с другой стороны генерируете URL, используя, например,

reverse( 'app:name', kwargs={ 'pk': my_mapping_function( object.pk) } )

Я не буду добровольно предоставлять такую функцию отображения, потому что, опубликовав ее, я сразу же сделаю ее гораздо менее полезной! (Тривиальным вариантом будет перестановка битов целого числа pk в новом порядке. Для менее тривиальных вариантов обратитесь к математику).

Я по-прежнему остаюсь при своем замечании, что это пример неправильной вещи. Если угадывание значений pk ставит под угрозу безопасность приложения, то "безопасность через неизвестность" не лучше, и этот ответ является примером такого

При этом, хасиды могут быть полезны.

Вернуться на верх