Как сгенерировать идентификатор для вновь созданного экземпляра модели с помощью django и DRF?
Я пытаюсь понять, как создавать экземпляры модели в моем представлении. Я написал метод в классе вне представления, который я использую для генерации случайного идентификатора для создаваемого экземпляра модели:
def generate_random_id(self, MyModel):
""" Picks a random id for an object to be created in POST"""
random_object = None
if random_object is None:
random_object = random.randrange(1, MyModel.objects.all().count() + 1)
while MyModel.objects.all().filter(id=random_object).exists():
random_object = random.randrange(1, MyModel.objects.all().count() + 1)
return random_object
Этот метод сработал для других экземпляров модели.
Я думаю, что проблема в самом представлении.
views.py
...
tag = Tag.objects.create(
id=controller.generate_random_id(Tag),
name='randomlycreatedtagfor test',
language='de')
...
Я продолжаю получать эту ошибку:
duplicate key value violates unique constraint "app_tagging_pkey"
DETAIL: Key (id)=(57949) already exists.
Вот мой код для модели и сериализатора. Возможно, здесь я делаю что-то не так.
models.py
class Tag(models.Model):
name = models.CharField(max_length=256)
language = models.CharField(max_length=256)
objects = models.Manager()
def save(self, *args, **kwargs):
if not self.id:
self.created = timezone.now()
return super().save(*args, **kwargs)
def create(self, validated_data):
tag_data = validated_data.pop('tag')
Tag.objects.create(**tag_data)
return tag_data
def __str__(self):
return self.name or ''
serializers.py
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('id', 'name', 'language')
def create(self, validated_data):
return Tag.objects.create(**validated_data)
def to_representation(self, data):
data = super().to_representation(data)
return data
Есть ли способ генерировать идентификатор более простым способом?
Прежде всего, вам не нужно генерировать идентификаторы вручную, но если вы действительно хотите внедрить подобный код в свою программу, я думаю, что реальный недостаток находится здесь:
random_object = random.randrange(1, MyModel.objects.all().count() + 1)
while MyModel.objects.all().filter(id=random_object).exists():
random_object = random.randrange(1, MyModel.objects.all().count() + 1)
Я вижу, что объект random_object пытается создать случайное число из одного и того же банка чисел, что рано или поздно приведет к ошибке. Здесь просто недостаток логики, и это действительно просто напрашивается на ошибку. Для получения случайных идентификаторов попробуйте использовать что-то вроде GUID в качестве id.
Проверьте https://docs.djangoproject.com/en/4.0/topics/db/models/#automatic-primary-key-fields в документации.
Django по умолчанию предоставляет поле id в качестве primary_key, поэтому вам не нужно вручную вставлять его в модель, просто удалите строку, удалите файлы миграции и файл DB, makemigrations => migrate затем попробуйте.