python - Esfinge y aplicaciones Django reutilizables.
documentation python-sphinx (3)
Problema
Mientras intentaba generar la documentación de la esfinge para una aplicación Django reutilizable, encontré el siguiente error. Cuando la esfinge analiza el código model.py
, se ve frustrada por el código que está intentando acceder a la configuración del proyecto Django. Como se trata de una aplicación independiente / reutilizable , no hay un proyecto principal que proporcione estos ajustes, es decir, no hay un archivo ROOT/PROJECT/PROJECT/settings.py
.
Preparar
En aras de la claridad aquí es lo que he hecho. Recorra lo que sería la carpeta de proyecto habitual cd ROOT/PROJECT
y cree una aplicación django-admin startapp APPLICATION
que produzca la siguiente estructura
/ROOT/
/PROJECT/
/APPLICATION/
admin.py
apps.py
models.py
tests.py
views.py
Nota : No hay archivos /ROOT/PROJECT/PROJECT/*.py
porque no /ROOT/PROJECT/PROJECT/*.py
a la carpeta cd root
y django-admin createproject
un proyecto usando django-admin createproject
como normalmente se podría.
A continuación se crea la documentación de sphinx spinx-quickstart docs
produce la siguiente estructura adicional.
/ROOT/
/PROJECT/
/docs/
/source/
...
conf.py
make.bat
Es decir, los documentos están construidos junto a la APPLICATION
.
Pregunta
¿Qué conf.py
en conf.py
para cargar correctamente la aplicación sin que haya un archivo settings.py
?
Deberes
Al intentar resolver esto, he examinado varias preguntas de SO, Blogs y Django Docs y no he encontrado una solución sucinta. Como esto se ha preguntado varias veces antes en SO, me gustaría motivarlo para que no se cierre como un duplicado, si la respuesta en el duplicado propuesto utiliza uno de estos fragmentos como su solución.
Falla con
AppRegistryNotReady
from django.conf import settings settings.configure()
Similar al primer método de falla, es decir, emite
AppRegistryNotReady
from django.conf import settings settings.configure() settings.INSTALLED_APPS += [''fintech'']
Falla con
ImproperlyConfigured
import django django.setup()
Hay una solución muy antigua que menciona el
setup_environ
obsoletofrom django.core.management import setup_environ from django.conf import settings settings.configure() setup_environ(settings)
Esta es también una respuesta favorita, pero falla si no hay un archivo
settings.py
.import django os.environ[''DJANGO_SETTINGS_MODULE''] = ''PROJECT.settings'' django.setup()
También he hecho esta pregunta bastante detallada, ya que las preguntas relacionadas con SO son bastante concisas y no especialmente útiles. Si es de alguna ayuda estoy usando Django 1.10.
Actualizar
Desde entonces he descubierto que si uno importa su función de setup
de setuptools
versus distutils.core
puede invocar el script de configuración para compilar su documentación como en python setup.py build_sphinx -b BUILDER
Probablemente sea mejor volver a preguntar esto cuando se invoque a setup.py
over docs/conf.py
través de make.bat
o MakeFile
proporcionado por Sphinx.
Sin embargo, sospecho que el resultado sería similar, es decir, incluir las respuestas proporcionadas en docs/conf.py
o, alternativamente, en setup.py
, ambas deben llamarse dentro de la misma sesión de Python, después de todo.
No es una respuesta a la pregunta.
¿Qué
conf.py
enconf.py
para cargar correctamente la aplicación sin que haya un archivosettings.py
?
pero un enfoque alternativo: coloque un proyecto Django mínimo y viable en el paquete reutilizable . Se puede utilizar para ejemplos de implementación, pruebas (incluida la cobertura de código), desarrollo y generación de documentos. Lo hacemos de esa manera en los repositorios privados de nuestra compañía y he visto algunos paquetes de django en github que también lo hacen.
Una estructura típica de mis paquetes se ve así:
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
En docs/conf.py
compruebo una variable de entorno de configuración y uso el proyecto de demostración si no se da:
if not os.environ.get(''DJANGO_SETTINGS_MODULE''):
os.environ[''DJANGO_SETTINGS_MODULE''] = ''mypackage_demo.settings''
django.setup()
De esa forma, podría construir los documentos utilizando otro proyecto configurando la variable de entorno DJANGO_SETTINGS_MODULE
antes de llamar a sphinx
.
settings.py
solo contiene la configuración mínima necesaria para ejecutar la aplicación. El mínimo absoluto para que Django funcione son estos:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = ''''
INSTALLED_APPS = [
''mypackage''
]
Si no desea que su documentación dependa de un proyecto de "demostración", puede crear manualmente la configuración en su conf.py
En la sección de configuración de ruta:
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
Ahora Sphinx puede importar los módulos de la aplicación sin tener un proyecto settings.py
. Se pueden pasar otras configuraciones a settings.configure()
.
Tuve el mismo problema con Django 1.11 y Sphinx 1.5.5. No logré que funcionara correctamente y tampoco funcionaron todas las soluciones que mencionaste anteriormente. Al final, lo resolví agregando esto a mi 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()