Reputation: 1
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
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
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