tutorial sirven que para migrations migraciones migracion makemigrations las forzar force eliminar borrar django django-models django-migrations

sirven - Las migraciones de Django agregan campo con el valor predeterminado como función del modelo



para que sirven las migraciones en django (3)

Agregué un nuevo campo que no admite nulos a mi modelo de Django y trato de usar las migraciones para implementar ese cambio. ¿Cómo establecería el valor predeterminado para usar para que los modelos existentes sean una función de esos modelos en lugar de una constante?

Como ejemplo, digamos que anteriormente tenía un campo created_on y acabo de agregar un campo updated_on cuyo valor quiero establecer inicialmente en el created_on del modelo. ¿Cómo haría esto en una migración?

Esto es con lo que estoy tratando de comenzar:

migrations.AddField( model_name=''series'', name=''updated_as'', field=models.DateTimeField(default=????, auto_now=True), preserve_default=False, ),


¡Acabo de aprender a hacer esto con una sola migración!

cuando ejecuta makemigrations django debe pedirle que establezca un valor predeterminado único. Defina todo lo que pueda aquí para mantenerlo feliz, y terminará con la migración AddField que mencionó.

migrations.AddField( model_name=''series'', name=''updated_as'', field=models.DateTimeField(default=????, auto_now=True), ),

Cambie esta operación en 3 operaciones:

  1. Inicialmente, haga que el campo sea nulo, por lo que se agregará la columna.
  2. llamar a una función para rellenar el campo según sea necesario.
  3. alterar el campo (con AlterField ) para que no sea anulable (como el anterior, sin ningún valor predeterminado).

así que terminas con algo así como

migrations.AddField( model_name=''series'', name=''updated_as'', field=models.DateTimeField(null=True, auto_now=True), ), migrations.RunPython(set_my_defaults), migrations.AlterField( model_name=''series'', name=''updated_as'', field=models.DateTimeField(auto_now=True), ),

con su función definida como algo así como:

def set_my_defaults(apps, schema_editor): Series = apps.get_model(''myapp'', ''Series'') for series in Series.objects.all().iterator(): series.updated_as = datetime.now() + timedelta(days=series.some_other_field) series.save()

excepto, ya sabes, no es terrible.


También debe definir un reverso para su función set_my_defaults() , en caso de que desee revertir la migración en el futuro.

def reverse_set_default(apps, schema_editor): pass

La función inversa en este caso no necesita hacer nada, ya que está eliminando el campo.

Y agréguelo a RunPython:

migrations.RunPython(set_my_defaults, reverse_set_default),


Tienes que hacerlo en dos migraciones. En primer lugar, agregue su campo, pero haga que se pueda agregar un valor nulo. Cree un archivo de migración como de costumbre. Después de eso configure su campo para que no se pueda nulos y ejecute migraciones de nuevo, pero no deje de migrar todavía. Abra la segunda migración y defina una función en la parte superior:

def set_field_values(apps, schema_editor): # use apps.get_model("app_name", "model_name") and set the defualt values

luego, en su archivo de migración hay una lista de operaciones. Antes de la operación de campo alter agregar

RunPython(set_field_values)

y debería hacerlo