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.
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
.