4

I'm having difficulty calling a django script. Here is what I'm currently doing in my root directory:

>>> import os
>>> os.environ['DJANGO_SETTINGS_MODULE'] = 'settings.py'
>>> from django.conf import settings
>>> settings.configure()
>>> settings.DATABASES
{}

The settings.DATABASES should not be empty, so I know I haven't initialized the project correct. How would I do this in django2.1? I used to be able to do this easily using import settings; setup_environ(settings), but not anymore.

Note: I'm looking to be able to run the above from any directory. Here is an example from trying to import my project from tmp:

(V) david$ cd /tmp && python

>>> import django
>>> from django.conf import settings
>>> settings.configure()
>>> django.setup()
>>> from users.models import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'users'

3 Answers 3

3

The 2.1 docs state that you need to use setup() now. Relevant snippet:

import django
from django.conf import settings

settings.configure()
django.setup()

# Now this script or any imported module can use any part of Django it needs.
from myapp import models

Here is the full documentation.

Sign up to request clarification or add additional context in comments.

6 Comments

Could you please explain what the line from myapp import myapp_defaults means and does? What would be a real-world example of doing that part?
Also, let's say you are in a directory such as tmp. How would you have access to running from myapp import myapp_defaults ? It seems like in the above you need to be in the 'correct directory' in order to run it.
Sorry about the confusion, I just copied the code from the documentation. The link I provided to the documentation explains all of that in detail. I will modify my answer to be more clear, as that particular line doesn't pertain to your question.
In answer to the first question of what does the import do: docs.djangoproject.com/en/2.1/topics/settings/#the-basics. That is a detailed explanation of the construction of some default settings. To answer your second question: the from myapp import myapp_defaults you are correct that you would need to be in the right directory. I have gone ahead and removed that import from the answer as it doesn't really pertain to your situation.
right, I understand that part, but in order to do the above you need to be in the "correct directory". I've added an update to the question -- I think the issue here is I need to add the path to my os.path and also import the project settings from that path.
|
2

You don't need to run settings.configure(). To properly initialize, you could do something like:

if __name__ == '__main__':
    import sys, os
    sys.path.append(django_root)
    os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
    from django.conf import settings
    print (settings.DATABASES)

1 Comment

That will allow you to access the settings, but you need to add the settings configuration to the OS level environment. It works, but it isn't really standalone at this point because you're modifying the ENV. See notes here what that might not be a good idea: docs.python.org/3/library/os.html#os.environ
1

I have had this problem and my solution (script) is the result of hundreds of Django sites over the course of a decade.

Some solutions can inhibit the use of settings and this is the best working version of a stand alone script for running Django that I have been able to compile. This is faster than the Django shell generally (no need to exit and re-enter).

Above suggestions will work 98% of the time. Still, consider reviewing (and commenting) on this for a more robust way to run Django scripts. I have hit the "Exceptions" about 1-2x every year for a while until I got this script fully debugged via many projects.

"""
scratch.py
----->note the no .py-----v
clear; echo 'import scratch' | python manage.py shell
"""
from django.conf import settings
from django.core.wsgi import get_wsgi_application  # turns on app, access to DB

print(f'- - - - - - - - - - - - - - - - - - - - ')
print(f'settings: {settings}') 
print('settings.DEBUG: {}'.format(settings.DEBUG))

# settings.DEBUG = True
# etc

if not settings.DEBUG:
    # keeps this off prod, usually on git ignore as well
    print('SETTINGS NOT IN DEBUG, set to:')
    print(settings.DEBUG)
    raise(RuntimeError('Can not be run on production or when debug is False'))

application = get_wsgi_application()


print('READY!')
print(f'- - - - - - - - - - - - - - - - - - - - ')

# App ready, code below. Add imports, calls, etc below here.

Additionally this script can be run in an infinite loop, such as for monitoring, debugging, and other day to day Django operations. At the ned of the file just add the following, possibly with a sleep() and logging.

while True:
    pass

Call this script scratch.py from the same directory as manage.py. Call using the following syntax:

echo 'import scratch' | python manage.py shell

If you change the file name, then the import will need to be edited. This syntax loads the settings without needing to call settings.configure(). We leverage manage.py and that seems to solve the edge cases.

Note: This will NOT auto-reload on with changes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.