Запуск функции по умолчанию в моделях 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 была встроенная функция для этого.