walrusk
walrusk

Reputation: 1

shared django project structure

This is what the structure of my project is. This question will ignore the 'lib' directory:

project
    app
        data -> migrations, models, __init__.py
        prodsite -> settings.py, urls.py, wsgi.py, __init__.py
        testsite -> same as above
    lib
        data -> migrations, models, __init__.py
        prodsite -> settings.py, urls.py, wsgi.py, __init__.py, common models
        testsite -> same as above
    tools
        manage.py

I want to be able to run:

python tools/manage.py app.prodsite (makemigrations/migrate) app

It was not hard to modify manage.py so that it adds the root directory to the system path, sets the django environment variable to 'app.prodsite', and deletes that argument from sys.argv, before continuing on with what manage.py normally does. I could not manage to get rid of the last parameter without causing errors:

#!/usr/bin/env python
import os
import sys
import inspect

def main():
    sys.path.append(os.getcwd()) # allow reative to cwd, not just module.py.
    if "DJANGO_SETTINGS_MODULE" not in os.environ:
        if len(sys.argv) < 3:
            print("Error in command: {}".format(" ".join(sys.argv)))
            print("manage.py should be called like:\r\n"
                  "manage.py <app> <operation>.")
            return
        os.environ.setdefault("DJANGO_SETTINGS_MODULE",
                              "{}.settings".format(sys.argv[1]))
        del sys.argv[1]
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)

if __name__ == "__main__":
    main()

These are the other relevant files:

# project.app.data:
class M(Model):
    class Meta:
        app_label = 'app.data'
    a: bool
    b: str
    c: float

# project.app.data.apps
class DataConfig(AppConfig):
    name = 'app.data'

# project.app.data.__init__
default_app_config = 'app.data.apps.DataConfig'

# project.app.prodsite.settings
ROOT_URLCONF = 'app.prodsite.urls'
WSGI_APPLICATION = 'app.prodsite.wsgi.application'
INSTALLED_APPS += ['app.data', 'app.micsite']

If I try running 'python bldtool/manage.py app.prodsite makemigrations app.data', I get an error asking if app.data is in INSTALLED_APPS.

No errors are generated if I only include 'app' in INSTALLED_APPS, but then django does not detect any changes and does not generate a migrations directory. (I have tried creating a migrations directory with init.py, with no success, either)

What can I do to make this work as expected?

Upvotes: 0

Views: 175

Answers (2)

walrusk
walrusk

Reputation: 1

The configuration that works for me in this particular case is:

# project.app.data:
class M(Model):
    class Meta:
        app_label = 'data' # Not full path
    a: bool
    b: str
    c: float

# project.app.data.apps
class DataConfig(AppConfig):
    name = 'app.data'

# project.app.data.__init__
# Empty

# project.app.prodsite.settings
ROOT_URLCONF = 'app.prodsite.urls'
WSGI_APPLICATION = 'app.prodsite.wsgi.application'
INSTALLED_APPS += ['app.data', 'app'] # No need for app.micsite

The above (along with the modified manage.py) allows me to perform:

python tools/manage.py app.prodsite [makemigrations|migrate] data

Upvotes: 0

razieh babaee
razieh babaee

Reputation: 298

According to django documentations:

A list of strings designating all applications that are enabled in this Django installation. Each string should be a dotted Python path to:

  • an application configuration class (preferred), or
  • a package containing an application.

Also, migrations directories ( with __init__.py files inside them) should be created before running makemigrations without specifying app name, otherwise, no changes will be detected by makemigrations command. But if you specify app name, makemigrations will work even without migrations directory.

Upvotes: 2

Related Questions