relaciones - forzar migracion django
Migraciones de Django RunPython no puede llamar a los métodos de modelo (2)
Estoy creando una migración de datos usando el método RunPython
. Sin embargo, cuando intento ejecutar un método en el objeto, ninguno está definido. ¿Es posible llamar a un método definido en un modelo usando RunPython
?
¿Llamó a su modelo como se dice en la documentación?
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()
Migración de datos Porque en este punto, no puede importar su Modelo directamente:
from yourappname.models import Person
Actualizar
El código interno de Django está en este archivo django / db / migrations / 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)
Solo hay campos que son clones en una instancia modelo "falsa":
MyModel.__module__ = ''__fake__''
Los métodos de modelo no están disponibles en las migraciones, incluidas las migraciones de datos.
Sin embargo, hay una solución, que debería ser bastante similar a llamar a los métodos de modelo. Puede definir funciones dentro de las migraciones que imitan los métodos de modelo que desea usar.
Si tuvieras este método:
class Order(models.Model):
''''''
order model def goes here
''''''
def get_foo_as_bar(self):
new_attr = ''bar: %s'' % self.foo
return new_attr
Puede escribir la función dentro de la secuencia de comandos de migración como:
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()
Entonces úsala en migraciones:
class Migration(migrations.Migration):
dependencies = [
(''order'', ''0001_initial''),
]
operations = [
migrations.RunPython(save_foo_as_bar)
]
De esta forma, las migraciones funcionarán. Habrá un poco de repetición de código, pero no importa porque se supone que las migraciones de datos son una operación única en el estado particular de una aplicación.