Запуск функции по умолчанию в моделях Django для каждого текущего объекта

models.py

class Subscription(models.Model):
    
    #... many fields ...
    
    # I added this field when I already had many objects
    uniqueSubscriptionId = models.CharField(default=generateUniqueSubscription, max_length=30)

generateUniqueSubscription

from django.utils.crypto import get_random_string


def generateUniqueSubscription():

    return get_random_string(20)

Проблема в том, что когда я запускаю миграции, все мои старые объекты получают одинаковые uniqueSubscriptionId. Я хочу, чтобы каждый старый объект получал уникальный uniqueSubscriptionId.

Как я могу это сделать?

одним из возможных решений является:
создать utils.py

from django.utils.crypto import get_random_string


def generateUniqueSubscription(subscription_id):

    return get_random_string(20)+str(subscription_id)

и затем перейдите к python manage.py shell вызовите этот utils.py и передайте subscription.pk этой функции, чтобы у вас была уникальная строка для обновления всех других значений в базе данных. Это может быть другое решение, где вам нужно переопределить метод сохранения.

Вот что я сделал:

models.py

def updateOldSubscriptionObjs(apps, schema_editor):
    old_subscription_model = apps.get_model("app_label", "Profile")

    for obj in old_subscription_model.objects.all():
        obj.uniqueSubscriptionId = generateUniqueSubscription()
        obj.save()

class Subscription(models.Model):
    
    #... many fields ...
    
    # I added this field when I already had many objects
    uniqueSubscriptionId = models.CharField(default=generateUniqueSubscription, max_length=30)

Затем я запустил makemigrations:

python manage.py makemigrations

Затем отредактировал последний файл миграции:

class Migration(migrations.Migration):

    dependencies = [
        # forget this
    ]

    operations = [
        # .... many things ...
        
        migrations.RunPython(updateOldProfileObjs)
    ]

Затем пробежал migrate:

python manage.py migrate

И вуаля, все старые объекты были обновлены, а также любой новый объект также будет обновлен, как я указал по умолчанию.

Если вы ленивы, как я, и не хотите делать эти вещи, тогда откройте django python shell:

python manage.py shell

и затем выполните эту функцию в shell:

def updateOldSubscriptionObjs():

    for obj in Subscription.objects.all():
        obj.uniqueSubscriptionId = generateUniqueSubscription()
        obj.save()

Хотелось бы, чтобы в django была встроенная функция для этого.

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