[Fixed]-How to make migrations for a reusable Django app?

21đź‘Ť

âś…

Actually, you don’t need to have project, all you need is settings file and script, that runs migrations creation.
Settings must contain folowing (minimum):

# test_settings.py

DEBUG = True

SECRET_KEY = 'fake-key'

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'your_app'
]

And the script, that makes migrations should look like this:

# make_migrations.py

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_settings")
    from django.core.management import execute_from_command_line
    args = sys.argv + ["makemigrations", "your_app"]
    execute_from_command_line(args)

and you should run it by python make_migrations.py. Hope it helps someone!

👤Compadre

11đź‘Ť

You need a functional Django project (with your app installed in it) to make migrations.

A common way to do this is to have a “test” project which contains the bare necessities of a Django project, that you can run to make migrations etc. The migrations will be created in the right place inside your app directory so you can still have proper version control etc within your own reusable app.

The migrations created in this way will be self-contained (assuming your models don’t depend on models from other apps) and can be shipped as part of your packaged, reusable app.

Many of the larger Django-based projects actually ship a test project as part of their code, so that developers can quickly get it running in order to test apps and make migrations etc.

👤solarissmoke

4đź‘Ť

Create your_app/migrations_settings.py file:

SECRET_KEY = 'fake-key'

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'your_app'
]

then

export DJANGO_SETTINGS_MODULE=yourapp.migrations_settings
django-admin makemigrations yourapp
👤Kangur

2đź‘Ť

Real Python has a tutorial on writting a reusable Django App.

The chapter Bootstrapping Django Outside of a Project has a very interesting example:

#!/usr/bin/env python
# boot_django.py

"""
This file sets up and configures Django. It's used by scripts that need to
execute as if running in a Django server.
"""

import os

import django
from django.conf import settings


BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "your_app"))


def boot_django():

    settings.configure(
        BASE_DIR=BASE_DIR,
        DEBUG=True,
        DATABASES={
            "default":{
                "ENGINE":"django.db.backends.sqlite3",
                "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
            }
        },
        INSTALLED_APPS=(
            "django.contrib.auth",
            "django.contrib.contenttypes",
            "your_app",
        ),
        TIME_ZONE="UTC",
        USE_TZ=True,
    )

    django.setup()

And then:

#!/usr/bin/env python
# makemigrations.py

from django.core.management import call_command
from boot_django import boot_django

boot_django()
call_command("makemigrations", "your_app")
👤raratiru

Leave a comment