Я создаю миграцию данных с использованием метода RunPython
. Однако, когда я пытаюсь запустить метод на объекте, не определены. Можно ли вызвать метод, определенный на модели, используя RunPython
?Django-миграции RunPython не удалось вызвать методы модели
ответ
Вы назвали свою модель, как указано в документации?
def combine_names(apps, schema_editor):
# We can't import the Person model directly as it may be a newer
# version than this migration expects. We use the historical version.
Person = apps.get_model("yourappname", "Person")
for person in Person.objects.all():
person.name = "%s %s" % (person.first_name, person.last_name)
person.save()
Data-Migration Потому что на данный момент, вы не можете импортировать модели напрямую:
from yourappname.models import Person
Update
Внутренний код Джанго в этом файле Джанго/DB/Миграции /state.py django.db.migrations.state.ModelState # construct_fields
def construct_fields(self):
"Deep-clone the fields using deconstruction"
for name, field in self.fields:
_, path, args, kwargs = field.deconstruct()
field_class = import_string(path)
yield name, field_class(*args, **kwargs)
Существует только поля, которые являются клонами в «поддельные» модели, например:
MyModel.__module__ = '__fake__'
методы модели не доступны в миграции, в том числе и миграции данных.
Однако есть обходное решение, которое должно быть очень похоже на вызов методов модели. Вы можете определять функции внутри миграций, которые имитируют те методы модели, которые вы хотите использовать.
Если у вас этот метод:
class Order(models.Model):
'''
order model def goes here
'''
def get_foo_as_bar(self):
new_attr = 'bar: %s' % self.foo
return new_attr
Вы можете написать функцию в сценарий миграции, как:
def get_foo_as_bar(obj):
new_attr = 'bar: %s' % obj.foo
return new_attr
def save_foo_as_bar(apps, schema_editor):
old_model = apps.get_model("order", "Order")
for obj in old_model.objects.all():
obj.new_bar_field = get_foo_as_bar(obj)
obj.save()
Затем используйте его в миграции:
class Migration(migrations.Migration):
dependencies = [
('order', '0001_initial'),
]
operations = [
migrations.RunPython(save_foo_as_bar)
]
Этот путь миграции будет Работа. Будет немного повторения кода, но это не имеет значения, поскольку миграция данных должна быть однократной операцией в конкретном состоянии приложения.
Да. вы можете получить доступ к полям на модели, но не методы моделей. – user2954587
методы не сработали для меня! –