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.