3

I've put the following code at the top of my script file

 os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'momsite.conf.local.settings')
 django.setup()

Now I can import my django apps and run small snippets (to mainly test stuff)

I'd like to import all the models registered through settings.INSTALLED_APPS

I know https://github.com/django-extensions/django-extensions does this when running manage.py shell_plus it automatically imports all the models and more.

I'm looking at their code. not sure if I'll make sense out of it.

https://github.com/django-extensions/django-extensions/blob/3355332238910f3f30a3921e604641562c79a0a8/django_extensions/management/commands/shell_plus.py#L137

at the moment, I'm doing the following, and I think it is importing models, but not available in the script somehow

 from django_extensions.management.shells import import_objects
 from django.core.management.base import BaseCommand, CommandError

 options = {}
 style = BaseCommand().style
 import_objects(options, style)
  • edit.. answer adopted from dirkgroten

import_objects internally calls from importlib import import_module Apparently, we need to populate globals() with imported class

 options = {'quiet_load': True}
 style = BaseCommand().style

 imported_objects = import_objects(options, style)
 globals().update(imported_objects)
eugene
  • 39,839
  • 68
  • 255
  • 489
  • "Now I can import my django apps and run small snippets (to mainly test stuff)" => Note that you really don't need all this overhead for this, cf https://stackoverflow.com/questions/16853649/how-to-execute-a-python-script-from-the-django-shell – bruno desthuilliers Dec 10 '19 at 13:02
  • "I'd like to import all the models registered through settings.INSTALLED_APPS" => looks like the part you want is here https://github.com/django-extensions/django-extensions/blob/3355332238910f3f30a3921e604641562c79a0a8/django_extensions/management/shells.py#L238 - everything around is some very generalized (and overcomplicated IMHO) stuff that tries to deal with every possible situation. – bruno desthuilliers Dec 10 '19 at 13:05
  • I've managed to do the importing, but thing is it is not imported... :( @brunodesthuilliers – eugene Dec 10 '19 at 13:12

2 Answers2

5

After you run django.setup(), do this:

from django.apps import apps
for _class in apps.get_models():
    if _class.__name__.startswith("Historical"): 
        continue
    globals()[_class.__name__] = _class

That will make all models classes available as globals in your script.

dirkgroten
  • 20,112
  • 2
  • 29
  • 42
0

Create a management command. It will automagically load django() and everything. Then in your command you simply start your command. ./manage.py mytest

#myapp/management/commands/mytest.py
from django.core.management.base import BaseCommand, CommandError
from myapp.sometest import Mycommand

class Command(BaseCommand):
    help = 'my test script'

    def add_arguments(self, parser):
        pass
        # parser.add_argument('poll_ids', nargs='+', type=int)

    def handle(self, *args, **options):
        Mycommand.something(self)

which will call the actuall script:

#sometest.py
from .models import *
class Mycommand():
   def something(self):
       print('...something')
Alex
  • 5,759
  • 1
  • 32
  • 47