blog.dbrgn.ch

Creating Django Oscar Initial Data Migration

written on Tuesday, March 24, 2015 by

I'm working on an online shop for our local hackerspace Coredump. To implement it, we chose django-oscar because I already know how to deal with Django and because it seems to be very customizeable.

In the docs it is mentioned that every shop needs a product class and a fulfillment partner. The proper way to implement that is to create a data migration.

The docs link to django-south though, the 3rd party database migration library that has been superceded with Django's own migration framework. So the instructions are not 100% clear anymore. After some failed attempts, I worked out how to properly create data migrations for Oscar.

1. Create a Django app

First of all, you need a django app to contain your data migrations. If you haven't created one yet, do it now:

$ ./manage.py startapp data

Then add it to INSTALLED_APPS in your settings.py.

I'd recommend to also create an initial migration, so that your data migration isn't the first one.

$ ./manage.py makemigrations --empty data

2. Create a data migration

Now you can create an empty data migration. Django's migration framework doesn't differentiate between data migrations and schema migrations anymore, so you can just use the --empty argument:

$ ./manage.py makemigrations --empty data

3. Find dependencies

It is recommended to create initial instances of the following models:

  • Product Category
  • Product Class
  • Fulfillment Partner
  • Partner Address

Additionally, if you don't import countries with ./manage.py oscar_populate_countries, you need to create a Country instance.

In order to create model instances for other apps, you need them as dependencies. All these models are created in the corresponding initial migration, therefore you can use the following dependency list:

dependencies = [
    # Your own app
    ('data', '0001_initial'),
    # Oscar apps
    ('catalogue', '0001_initial'),
    ('partner', '0001_initial'),
    ('address', '0001_initial'),
]

4. Write RunPython functions

For each of these model types we'll create a function that can be run with the migrations.RunPython operation. Here's the example for the country:

def create_countries(apps, schema_editor):
    Country = apps.get_model("address", "Country")
    Country.objects.create(
        iso_3166_1_a2='CH',
        iso_3166_1_a3='CHE',
        iso_3166_1_numeric='756',
        printable_name='Schweiz',
        name='Schweiz',
        display_order=0,
        is_shipping_country=True)

It's important that you use address as app label and not oscar.apps.address or oscar.apps.address.models.

Add matching functions for all other data types.

5. Example

That's it. If you want to see an example of such a data migration, see https://github.com/coredump-ch/shop/blob/master/apps/data/migrations/0002_product_types_and_partners.py.

This entry was tagged django and python