Home > Software engineering >  Can't save modified models.py because of (already applied) migration file - Django 3
Can't save modified models.py because of (already applied) migration file - Django 3

Time:08-24

I previously added 2 functions in my models.py for my upload path. But i noticed later the 2 functions were similar.

def upload_path(instance, fl_file_name):
    supplier = str(instance.fl_supplier).replace(' ', '-')
    return ('sources/{0}/{1}'.format(supplier.lower(), fl_file_name))


def upload_path_stock(instance, fl_file_name):
    supplier = str(instance.fl_st_supplier).replace(' ', '-')
    return ('sources/{0}/{1}'.format(supplier.lower(), fl_file_name))

A bit lower, my model was written like this

class Flow(models.Model):
[...]
    fl_file_name = models.FileField(
        max_length=50, upload_to=upload_path_stock, verbose_name='Nom fichier')

I tried to comment the function def upload_path_stock and changed the property of my model like this :

class Flow(models.Model):
[...]
    fl_file_name = models.FileField(
        max_length=50, upload_to=upload_path, verbose_name='Nom fichier') # <<<< HERE

But when saving, an error raised :

File "/Users/[...]/migrations/0063_auto_20220822_1834.py", line 27, in Migration field=models.FileField(max_length=50, upload_to=flows.models.upload_path_stock, verbose_name='Nom fichier'), AttributeError: module 'flows.models' has no attribute 'upload_path_stock'

This line prevents saving the file to be saved because upload_path_stock is mentioned there:

migrations.AlterField(
            model_name='flowstock',
            name='fl_st_file_name',
            field=models.FileField(max_length=50, upload_to=flows.models.upload_path_stock, verbose_name='Nom fichier'),
        ),

So I uncommented the unwanted function and proceed again with a new migration. Now the last migration is #64. But even though the migration 64 is applied, the error is still mentioned in the 63 when I comment out the function again and try to save my model.

Can I modify the new path directly in migration 63 file or should I process another safer way

CodePudding user response:

From all you are refering to I think you might run into this problem:

References to functions in field options such as upload_to and limit_choices_to and model manager declarations with managers having use_in_migrations = True are serialized in migrations, so the functions and classes will need to be kept around for as long as there is a migration referencing them. Any custom model fields will also need to be kept, since these are imported directly by migrations.

Source (same for your django version btw.)

So as I always try to stick to the documentation, keep the code and mark it with a do-not-delete-warning and a comment referring to these lines in the documentation. Yes this seems Ugly, but if you do not have the option to manually interfere in migration files, like squashing or reverting then this seems to be the solution.

CodePudding user response:

You can just delete all the migrations inside the migration file. I would recommend to do this for all apps, related models don't like it when relations disappear from migrations. Do not delete the migrations file itself, or the __init__.py file insite it.

So, just delete them, makemigrations and migrate again.

This should be safe, but just in case, backup your database first.

  • Related