En la documentación dice,
"Pase el método RunPython.noop a code o reverse_code cuando desee que la operación no haga nada en la dirección dada. Esto es especialmente útil para hacer que la operación sea reversible".
A veces es posible que quieras revertir una migración. Por ejemplo, ha agregado un campo, pero ahora desea que la base de datos vuelva al estado anterior a la migración. Puede hacer esto revirtiendo la migración [Django-doc] con el comando:
python3 manage.py migrate app_name previous_migration_name Luego, Django buscará cómo puede migrar de regreso al previous_migration_name y realizar las operaciones necesarias. Por ejemplo, si cambió el nombre de un campo de foo a bar , entonces Django lo cambiará de bar a foo .
Otras operaciones no son reversibles. Por ejemplo, si elimina un campo en la migración y ese campo no tiene un valor predeterminado y no admite valores NULL , esto no se puede revertir. Esto tiene sentido ya que lo contrario de eliminar un campo es agregar un campo, pero dado que no hay ningún valor que tomar para los registros existentes, ¿qué debe completar Django para ese campo que se vuelve a crear para los registros existentes?
Un comando RunPython por defecto no es reversible. En general, en informática, no se puede determinar computacionalmente el reverso de una función, si existe. Esta es una consecuencia del teorema de Rice [wiki] . Pero a veces es posible. Si por ejemplo construimos una migración donde incrementamos un determinado campo con uno, entonces lo contrario es decrementar todos los campos con uno, por ejemplo:
from django.db.models import F from django.db import migrations def forwards_func(apps, schema_editor): MyModel = apps.get_model('my_app', 'MyModel') db_alias = schema_editor.connection.alias MyModel.objects.using(db_alias).all().update( some_field=F('some_field')+1 ]) def reverse_func(apps, schema_editor): MyModel = apps.get_model('my_app', 'MyModel') db_alias = schema_editor.connection.alias MyModel.objects.using(db_alias).all().update( some_field=F('some_field')-1 ]) class Migration(migrations.Migration): dependencies = [] operations = [ migrations.RunPython( code=forwards_func, reverse_code=reverse_func ), ] Pero a veces es posible que una migración (de datos) no haga nada cuando la migra hacia adelante, o más común cuando la migra hacia atrás. En lugar de implementar cada vez una función vacía, puede pasar una referencia a noop , que no hace nada:
from django.db.models import F from django.db import migrations def forwards_func(apps, schema_editor): # … some action … pass class Migration(migrations.Migration): dependencies = [] operations = [ migrations.RunPython(code=forwards_func, reverse_code=migrations.RunPython.noop ), ]