17

I have a django project, which I document using reST in docstrings to do the following:

  1. Help diagloags within IDE
  2. Later on to build HTML documentation using Sphinx

My documentation shows up properly within IDE (PyCharm), however I can't configure Sphinx to generate HTML documentation for me.

Here is the structure of my project

+--------------------------------------------+
|  /saassapp         # django project path   |
|     /docs          # dir for sphinx        |
|        conf.py     # sphinx config file    |
|        ...                                 |
|     settings.py    # django settings       |
|     /studyview     # django app            |
|        ...
|     ...                                    |
+--------------------------------------------+

Any ideas? An examle of the conf.py file would be very useful. Thank you.

EDIT

My project name is saassapp and the module I am trying to make a doc for is called studyview.

miki725
  • 27,207
  • 17
  • 105
  • 121
  • 3
    Have you run the [spinx-quickstart](http://sphinx.pocoo.org/tutorial.html) script? It sets up the Sphinx environment for you. – mzjn Oct 14 '11 at 13:23
  • yes. I just can't figure out a proper config for it. no matter what I try, when I run the `make html` command, I get errors regarding importing django settings... – miki725 Oct 14 '11 at 18:36
  • You'll have to show us the errors that you get. – mzjn Oct 14 '11 at 18:53

6 Answers6

20

The migration features introduced in Django 1.7 prevents the previous answers from working on newer versions. Instead you will have to do a manual setup. Analogous to all previous answers you'll first have to make sure Django can find your settings, and then call django.setup() which will load the settings and setup your models. Add this to your Sphinx project's conf.py:

os.environ['DJANGO_SETTINGS_MODULE'] = 'projectname.settings'
import django
django.setup()
Simon
  • 3,667
  • 1
  • 35
  • 49
  • 1
    This works well, except if the ``automodule`` directive contains eg. ``:undoc-members:``. In that case, Sphinx extracts the documentation from the parent classes and misses some of them (for instance ``models.FileField``). This works well if ``:undoc-members:`` is removed and the class attributes are properly documented. – Raffi May 12 '16 at 08:36
  • I keep getting a `ImportError: No module named 'projectname'` when I try a `make html`. Do you know what it might be? – Joabe da Luz Dec 02 '16 at 21:12
  • @JoabMendes: Unless you explicitly named your Django project `projectname` you have to adjust that to whatever you named your project module. In other words, `DJANGO_SETTING_MODULE` should hold a valid python path pointing to your project's settings module. – Simon Dec 03 '16 at 08:07
  • @Simon it holds the projectname, I just used it as example haha. I specified the `DJANGO_SETTINGS_MODULE` but I'm using a separate settings architecture. Inside the main project folder I have a settings folder with `base`, `local ` and `production` settings files. Both, local and production import base. So my `DJANGO_SETTINGS_MODULE` is something like `projectname.settings.local`. Do you think I need a specific configuration in this case? (I have tried to edit the sys.path) Also, I cannot import any module directly in conf.py (My tree: http://pastebin.com/y0HqZ8pz) – Joabe da Luz Dec 03 '16 at 16:47
  • @JoabMendes Oh sorry, I thought that was literally the error message you got. I think it should work as long as you specify a complete Django settings file, regardless of where it's located. But as you can't import any other modules either I would first look into python path and/or virtualenv setup to make sure you can import the settings module in a python REPL. – Simon Dec 04 '16 at 11:25
  • @Simon I made a work around importing every module I wanted to autodoc directly in conf.py with their full paths (In this way for python 3.4: http://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path?answertab=active#tab-top). The only problem, as I said, is that I have to import manually all the modules. Well, thank you anyway for your attention. (: – Joabe da Luz Dec 05 '16 at 06:38
14

Add the following to your conf.py and you will not need to set DJANGO_SETTINGS_MODULE each time:

import sys, os

sys.path.append('/path/to/your/project') # The directory that contains settings.py

# Set up the Django settings/environment
from django.core.management import setup_environ
from myproject import settings

setup_environ(settings)
Mike Ryan
  • 1,408
  • 12
  • 16
12

With Django 1.6, I couldn't use the answer by @MikeRyan since from django.core.management import setup_environ has been deprecated. Instead, I went to my conf.py file and added the following:

import sys
import os

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'dataentry.settings'
from django.conf import settings

Let me explain each line:

  1. I used a relative path (two directories up), but you can go ahead and put an absolute path if you'd like
  2. My project name is dataentry and the settings.py file is inside that folder; change the name (dataentry) to your project name
Simon
  • 3,667
  • 1
  • 35
  • 49
Will
  • 11,276
  • 9
  • 68
  • 76
4

I think you have to make Sphinx aware of the DJANGO_SETTINGS_MODULE environment variable. So do

export DJANGO_SETTINGS_MODULE=mysite.settings

(or whatever is the right value for you)

Then execute

make html

in the same terminal session.

mzjn
  • 48,958
  • 13
  • 128
  • 248
0

Late but using Django>=1.9 and sphinx>=1.6.4 set the path equivalent to the project BASE_DIR in the conf.py

import django
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
os.environ["DJANGO_SETTINGS_MODULE"] = "project.settings"
django.setup()
jackotonye
  • 3,537
  • 23
  • 31
0

You actually don't need a separate settings module. It's sometimes easier to have one (when tests and doc share settings) but not required.

This is how dj-stripe sets up django for sphinx. The key here is the settings.configure call with INSTALLED_APPS as it is the only one setting key required (if your app does not require more of course):

import django
from django.conf import settings
from django.utils.encoding import force_text
from django.utils.html import strip_tags

import djstripe  # noqa


# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# sys.path.insert(0, os.path.abspath('.'))
cwd = os.getcwd()
parent = os.path.dirname(cwd)
sys.path.append(parent)


settings.configure(
    INSTALLED_APPS=[
        "django.contrib.admin",
        "django.contrib.auth",
        "django.contrib.contenttypes",
        "django.contrib.sessions",
        "django.contrib.sites",
        "jsonfield",
        "djstripe",
    ],
    SITE_ID=1,
    STRIPE_PUBLIC_KEY=os.environ.get("STRIPE_PUBLIC_KEY", ""),
    STRIPE_SECRET_KEY=os.environ.get("STRIPE_SECRET_KEY", ""),
)


django.setup()
Janusz Skonieczny
  • 17,642
  • 11
  • 55
  • 63