When creating a package, how do I manage migrations of a weak dependency?

Question:

I have a Django app that I would like to package and offer the community through PyPI repository. Its only strong dependance is Django. It also integrates nicely with Django CMS and offers additional integration for Django CMS. I plan to offer this additional functionality only to projects with Django CMS installed. (This is what I call a weak dependency – will install and work without it, but work even bitter with it.) Specifically, some models are only defined if the base model CMSPlugin from Django CMS is installed.

Is there a good/right way to manage migrations, though?

I cannot include migrations of models depending on CMSPlugin in the package since users w/o a Django CMS installations will not be able to run it.

If I omit the migrations depending on CMSPlugin users with Django CMS will create them on first installation. I fear, however, that on every update of the package those migrations will be lost on pip install upgrade when the package is overwritten.

Asked By: Fabian

||

Answers:

Since these models are not necessarily used in your package it is best to have them in another Django app, which can be a sub-app of your app or perhaps just one of the apps present in your package. If a user has installed CMSPlugin then they can now simply add this extra app of yours to the INSTALLED_APPS list to use it, this also comes with the benefit that your users now have the choice to use it or not.

This way you can also easily adapt your views if this app is installed or not by using the app registries is_installed method [Django docs]:

from django.apps import apps


def some_view(request):
    if apps.is_installed('yourpackage.path.to.weak_dependency_subapp'):
        # Weak dependency is present
    else:
        # Weak dependency is absent

Note: You would have to be careful though that you don’t import this apps models if it is not installed, otherwise it may give you some error since it would not be loaded.

Edit: To make the sub-app you can either do as you did by cd’ing to the apps directory and python ../manage.py startapp subappname or directly python manage.py startapp subappname <your_app>/subappname (The directory subappname needs to be made first) and then setting it’s app config’s name attribute to <your_app>.subappname.

Answered By: Abdul Aziz Barkat