While trying to generate sphinx documentation for a re-usable Django application I struck upon the following snafoo. When sphinx parses the model.py
code it is thwarted by the code therein trying to access the Django project settings. As this is a standalone/reusable application there is not a primary project providing these settings i.e. there is no ROOT/PROJECT/PROJECT/settings.py
file.
In the interest of clarity here is what I've done. Traverse to what would be the usual project folder cd ROOT/PROJECT
and create an application django-admin startapp APPLICATION
which produces the following structure
/ROOT/
/PROJECT/
/APPLICATION/
admin.py
apps.py
models.py
tests.py
views.py
Note : There are no /ROOT/PROJECT/PROJECT/*.py
files because I did not navigate to the root folder cd root
and create a project using django-admin createproject
as one normally might.
Next one creates the sphinx documentation spinx-quickstart docs
producing the following additional structure.
/ROOT/
/PROJECT/
/docs/
/source/
...
conf.py
make.bat
That is the docs are built next to the APPLICATION
.
What do I place within conf.py
to properly load the application without there being a settings.py
file ?
In trying to resolve this I have perused a number of SO Questions, Blogs and the Django Docs and not found a succinct solution. As this has been asked a few times before on SO I'd like to motivate that it not be closed as a duplicate, if the answer in the proposed duplicate uses one of these snippets as it's solution.
Fails with AppRegistryNotReady
from django.conf import settings
settings.configure()
Similar to the first method of failure i.e. emits AppRegistryNotReady
from django.conf import settings
settings.configure()
settings.INSTALLED_APPS += ['fintech']
Fails with ImproperlyConfigured
import django
django.setup()
There is a really old solution mentioning the deprecated setup_environ
from django.core.management import setup_environ
from django.conf import settings
settings.configure()
setup_environ(settings)
This is also a favourite answer but fails if there is no settings.py
file.
import django
os.environ['DJANGO_SETTINGS_MODULE'] = 'PROJECT.settings'
django.setup()
I've also made this question rather verbose as the related questions on SO are rather terse and not especially helpful. If it's any help I'm using Django 1.10.
I have since found that if one imports their setup
function from setuptools
versus distutils.core
that one may invoke the setup script to compile their documentation as in python setup.py build_sphinx -b BUILDER
It's probably best to re-ask this when invoking setup.py
over docs/conf.py
via either the make.bat
or the MakeFile
provided by Sphinx.
I suspect the outcome would be similar though, namely include the provided answers within docs/conf.py
or alternatively within setup.py
, both must be called within the same Python session after all.
If you don't want to make your documentation dependent on a "demo" project, then you can manually build the settings in your conf.py
. In the path setup section:
import django
from django.conf import settings
import os
import sys
# add path to sys.path (this might be different in your project)
sys.path.insert(0, os.path.abspath('..'))
# pass settings into configure
settings.configure(
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'my_reusable_app',
'any_other_dependencies',
]
)
# call django.setup to load installed apps and other stuff
django.setup()
# ... continue with rest of conf.py
Now Sphinx can import the app modules without having a project settings.py
. Other settings can be passed to settings.configure()
.
It's not an answer to the question
What do I place within
conf.py
to properly load the application without there being asettings.py
file ?
but an alternative approach: Put a minimal, viable Django project in the reusable package. It can be used for implementation examples, testing (including code coverage), development and doc generation. We do it that way in our company's private repositories and I have seen a few django packages on github that do it too.
A typical structure of my packages looks like this:
docs
├── conf.py
├── ... rst files
mypackage # the actual package
mypackage_demo # the Django project
├── .coveragerc
├── manage.py
├── settings.py
README.rst
requirements.txt
setup.py
In docs/conf.py
I check for a settings environment variable and use the demo project if non is given:
if not os.environ.get('DJANGO_SETTINGS_MODULE'):
os.environ['DJANGO_SETTINGS_MODULE'] = 'mypackage_demo.settings'
django.setup()
That way you could build the docs using another project by setting the DJANGO_SETTINGS_MODULE
environment variable before calling sphinx
.
settings.py
just contains the minimal configuration necessary to run the application. The absolute minimum for Django to work are these:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = ''
INSTALLED_APPS = [
'mypackage'
]
I did have the same issue with Django 1.11 and Sphinx 1.5.5. I did not manage to get it working properly and all the solutions you mentioned above did not work either. In the end I solved it by adding this to my Sphinx conf.py:
import sys, os
project_path = os.path.abspath('.')
# For Django to know where to find stuff.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
sys.path.append(project_path)
# For settings.py to load.
os.chdir(project_path)
# For the models to load.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With