How to develop/include a Django custom reusable app in a new project? Are there some guidelines? How to develop/include a Django custom reusable app in a new project? Are there some guidelines? python-3.x python-3.x

How to develop/include a Django custom reusable app in a new project? Are there some guidelines?


Additionally, a good workflow during development is to link the reusable app into your Django project. To easily achieve this pip install has the -e, --editable option, which in turn derives from the setuptools Development mode.

Reusable app:

django-myApp|--myApp|  |--models|     |--file1.py|     |--file2.py|--setup.py|--README.rst

Django setup:

my-django-project|--my_django_project|  |--settings.py|  |--urls.py|  |--wsgi.py|  |--...|--manage.py

With your virtualenv activated you can now link your reusable app to the project by running:

(myvenv) $ pip install --editable /path/to/django-myApp

Now, every change that you make in django-myApp is automatically reflected in my-django-project without the need to build/package the reusable app first.

This becomes convenient in many use cases. E.g. imagine developing the app to be compatible with Python 2.x and Python 3.x. With linking, you can install the app into two (or more) different Django setups and run your tests.


  1. When you package an app, is because you decided it was worth to use it across several projects and had some value on it's own. You can follow the guidelines to keep your app reusable and package once it is in a good state (minimal functionality working).Ok, you got your app ready, it does what you want, so now you want to separate it from your project? Follow the tutorial you linked for the guidelines on the folder structure and upload it to a repository. Add some tests too, they are a must have.You can now use a couple approaches to get it back into your project.

    • Package it and install it from the tar.gz via pip (or directly from repository)
    • Clone your repository as a submodule
    • Keep a copy in your project and update changes manually in the repository

I am not a fan of third one. Second option has its caveats but it can work. I definitely prefer first one.

Create a test project around your new app and use it to develop it's new features (with just the minimum requirements to test it), update your repository and finally update the app in your project via pip. Your app is now something that doesn't depend on your project, so don't tie your app to it.

  1. Did you add it to your INSTALLED_APPS? If you did, check that your models.py is accesible...try with the django shell. Try creating the migrations module to see if it works, that doesn't take long anyway.

  2. Finally the answer: No, your app is a different project on it's own now, you continue developing on a repository like you would do with any other project and then update like you would do with any other app that got a new version released. You don't need (nor should) touch your virtualenv's folders at all.

These are the steps for an update in your app:

  • You found a nasty bug or thought of some nice feature
  • You added the tests to cover it
  • You updated your code to enhance your app
  • You repeat the last couple steps until your app is stable again
  • If your app is in Pypi, you release a new package and update it from there, otherwise you update it from the repository.

This obviously takes longer than developing an app inside of your project, but doing it this way helps ensuring a good quality and that it won't introduce problems to your projects.


I ran into a similar situation while developing this library (django-nsync).

I "solved" the issue by creating a makemigrations.py script that sets up a minimal Django settings to include the 'app' and then makes a call to the makemigrations command.

The script looks like this:

def make_migrations():    from django.core.management import call_command    call_command('makemigrations', '<YOUR APP NAME>')if __name__ == '__main__':    import sys    # I need to add the 'src' folder to PYTHON PATH    sys.path.append('./src/')    try:        from django.conf import settings        settings.configure(            INSTALLED_APPS=[                '<ANY APPS YOUR APP DEPENDS ON>',                '<YOUR APP NAME>',            ],        )        import django        django.setup()    except ImportError:        import traceback        traceback.print_exc()        raise ImportError('To fix this error, sort out the imports')    make_migrations()

This script does not require a separate project in order to create the migrations.

NB: I tried to hook this into the setup.py stuff so that whenever you try to build (or more importantly release) the library it checks that the migrations are up to date / in source control. However, I gave up because:

  1. I hopefully won't have to do it much for the NSync library.
  2. It got messy quickly (like checking how many files in the migrations folder, then running the migrations, then checking again, then deleting the files? or leaving them? should I enforce this at release time? should I check with Git like bumpversion does? blah....)