Как добавить ненулевое уникальное значение в существующую модель Django с атрибутом по умолчанию

Мне нужно добавить поле slug в модель django, и я считаю, что лучше, когда оно не равно null. Итак, я пытаюсь добавить слаг в модель

slug = models.SlugField(
    'URL',
    unique=True,
    default=id_generator,
)

мой id_generator:

import string
import random
def id_generator():
    size=16
    chars=string.ascii_lowercase + string.digits
    return ''.join(random.choice(chars) for x in range(size))

Проблема в том, что когда я переношу изменения. Метод id_generator вызывается один раз и использует одно и то же значение для всех объектов модели. Итак, у меня есть повторяющаяся запись в уникальном поле. Как я могу генерировать уникальные значения? Джанго 1.11.5

P.S. Я понимаю, что я могу установить null = True и настроить метод сохранения модели, чтобы добавить слаг при сохранении.


person Eugeny Maksimov    schedule 28.09.2017    source источник
comment
Дополнительное замечание и, конечно, пограничный случай: в вашем id_generator нет ничего, что гарантировало бы уникальность, даже если бы он вызывался для каждого экземпляра.   -  person schwobaseggl    schedule 28.09.2017
comment
Возможный дубликат Добавить ненулевое и уникальное поле с уже заполненная модель   -  person schwobaseggl    schedule 28.09.2017


Ответы (1)


САМОЕ ВАЖНОЕ: у вас нет хорошего генератора для уникального слага, может быть лучше всего использовать, например, uuid

import uuid

slug = models.CharField(max_length=64, blank=True, unique=True, default=uuid.uuid4)

по add-unique-fields< /а>

  1. Добавлен null=True, без значения по умолчанию С переносом данных
  2. Изменить модель с текущим описанием в файле с миграцией.

пример первого шага миграции, замените YOUMODEL:

from __future__ import unicode_literals
import string
import random
from django.db import migrations, models


def id_generator():
    size=16
    chars=string.ascii_lowercase + string.digits
    return ''.join(random.choice(chars) for x in range(size))

def update_slug(pp, schema_editor):
    for instance in YOUMODEL.objects.all():
        #           ^^^^^^^
        instance.slug = id_generator()
        instance.save()


class Migration(migrations.Migration):

    operations = [
        migrations.AddField(
            model_name='YOUMODEL',
            #           ^^^^^^^
            name='slug',
            field=models.SlugField(null=True, verbose_name='URL'),
        ),
        migrations.RunPython(code=update_slug)

    ]
person Brown Bear    schedule 28.09.2017