0

I am migrating to django-oscar2.1

I have forked catalogue app, it has some existing migrations. Newly added field is_public is in migration #10. I have a custom migration #5 which is using create_from_breadcrumbs method. So when I tried to run migrate on fresh db migration#5 trigger error is_public field not exists in db.

create_from_breadcrumbs Oscar loads a model with latest state which contains is_public in models but not in db.

In migration #5 I am loading model like this Category = apps.get_model("catalogue", "Category")

Mark Waugh
  • 423
  • 1
  • 5
  • 10
  • its a issue related with theapp registry that has the historical versions of all your models loaded into it to match where in your history the migration sits. But the create_from_breadcrumbs using Category = get_model('catalogue', 'category') which loads the current state of models but the field not available in db. – Mark Waugh Jul 25 '20 at 08:47

1 Answers1

0

You cannot use create_from_breadcrumbs in a migration like that. The reason for this is explained in Django's documentation on migrations - that the version of the model used in external code may be different from the one that this migration expects - which is why it fails.

If you want to create model objects as part of your migration you need to use the historic version of the model in the migration. This means defining your own version of create_from_breadcrumbs, and using the historic version of the model as suggested by the Django documentation:

def create_from_breadcrumbs_for_migration(apps, schema_editor):
    Category = apps.get_model('catalogue', 'Category')
    # Perform logic to create categories here.


class Migration(migrations.Migration):

    dependencies = [
        ('catalogue', '0004_xxxx'),
    ]

    operations = [
        migrations.RunPython(create_from_breadcrumbs_for_migration),
    ]
    

That said, I would argue that migrations are not meant for this sort of data population in the first place. You would in my view be better off writing a separate management command for this, which you run after the migrations have been applied.

solarissmoke
  • 30,039
  • 14
  • 71
  • 73
  • I am following above direction but it gives me error. child = parent.get_children().get(name=name) AttributeError: 'Category' object has no attribute 'get_children' – Mark Waugh Jul 26 '20 at 07:09
  • Again, this is documented behaviour. See https://docs.djangoproject.com/en/2.2/topics/migrations/#historical-models and also https://stackoverflow.com/questions/28777338/django-migrations-runpython-not-able-to-call-model-methods - and is why you really should consider doing this in a management command. – solarissmoke Jul 26 '20 at 08:48