tutorial relaciones modelos migraciones migracion forzar datos borrar django django-models django-migrations

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__''

Github Django


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.