Giter Club home page Giter Club logo

sphinxcontrib-django's Introduction

GitHub Workflow Status

PyPi

Code coverage

Black Code Style

GitHub license

Documentation Status

logo

sphinxcontrib-django

This is a sphinx extension which improves the documentation of Django apps.

Features

Improvements for the output of Sphinx's autodoc for Django classes:

  • List all model and form fields as class parameters
  • Improve model field representations
  • Link related and reverse related fields to the referenced class
  • Hide irrelevant runtime information like declared_fieldsets, fieldsets and Meta from classes
  • Add information about autogenerated methods
  • Fix intersphinx mappings to Django modules
  • Custom text roles to cross-reference the documentations of Django (:setting:, :templatetag:, :templatefilter:, :fieldlookup:) and Sphinx (:event:, :confval:)

Installation

Install the package via pip:

pip install sphinxcontrib-django

Configuration

Add the following to your Sphinx config file conf.py:

# Add source directory to sys.path
sys.path.insert(0, os.path.abspath("../src"))

# Add sphinxcontrib_django to installed extensions
extensions = [
    "sphinxcontrib_django",
]

# Configure the path to the Django settings module
django_settings = "myapp.settings"

Optionally, you can include the table names of your models in their docstrings with:

# Include the database table names of Django models
django_show_db_tables = True                # Boolean, default: False
# Add abstract database tables names (only takes effect if django_show_db_tables is True)
django_show_db_tables_abstract = True       # Boolean, default: False

Optionally, you can extend amount of displayed choices in model fields with them:

# Integer amount of model field choices to show, default 10
django_choices_to_show = 10

Advanced Usage

If you want to run custom code which depends on Django, e.g. to monkeypatch your application during documentation build, you might run into an ImproperlyConfigured exception:

Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

Therefore, this Sphinx extension emits the event django-configured after django.setup() is finished, so you can run your code the following way in conf.py:

def patch_django(app):
    """
    Your custom code here
    """

def setup(app):
    app.connect("django-configured", patch_django)

Contributing

Pull requests are always welcome!

You can install all requirements of the development setup with the extras dev, test, doc and optional:

python3 -m venv .venv
source .venv/bin/activate
pip install -e .[dev,test,doc,optional]
pre-commit install

Run the tests and generate the coverage report with:

coverage run
coverage html

Build the documentation with:

cd docs
make html

The documentation is automatically deployed to Read the Docs.

sphinxcontrib-django's People

Contributors

cclauss avatar dependabot[bot] avatar emoffett avatar insspb avatar jdillard avatar mauler avatar miterion avatar raphaelm avatar rixx avatar timobrembeck avatar v-erena avatar vdboor avatar wesleykendall avatar whynothugo avatar zd42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sphinxcontrib-django's Issues

Add support for `ruff --select=DJ`

Motivation

% ruff --select=DJ # https://docs.astral.sh/ruff/rules/django-model-without-dunder-str

warning: The top-level linter settings are deprecated in favour of their counterparts in the `lint` section. Please update the following options in `pyproject.toml`:
  - 'ignore' -> 'lint.ignore'
  - 'select' -> 'lint.select'
tests/roots/test-docstrings/dummy_django_app/models.py:22:7: DJ008 Model does not define `__str__` method
tests/roots/test-docstrings/dummy_django_app/models.py:26:7: DJ008 Model does not define `__str__` method
tests/roots/test-docstrings/dummy_django_app/models.py:82:7: DJ008 Model does not define `__str__` method
tests/roots/test-docstrings/dummy_django_app/models.py:86:7: DJ008 Model does not define `__str__` method
tests/roots/test-docstrings/dummy_django_app/models.py:90:7: DJ008 Model does not define `__str__` method
tests/roots/test-docstrings/dummy_django_app/models.py:119:11: DJ008 Model does not define `__str__` method
tests/roots/test-docstrings/dummy_django_app/models.py:123:7: DJ008 Model does not define `__str__` method
Found 7 errors.

Proposed Solution

Edit pyproject.toml to fix the two warnings above and add DJ to the lint.select and then add .__str__() methods to the 7 Django models.

% ruff rule DJ008

django-model-without-dunder-str (DJ008)

Derived from the flake8-django linter.

What it does

Checks that __str__ method is defined in Django models.

Why is this bad?

Django models should define __str__ method to return a string representation
of the model instance, as Django calls this method to display the object in
the Django Admin and elsewhere.

Models without __str__ method will display a non-meaningful representation
of the object in the Django Admin.

Example

from django.db import models


class MyModel(models.Model):
    field = models.CharField(max_length=255)

Use instead:

from django.db import models


class MyModel(models.Model):
    field = models.CharField(max_length=255)

    def __str__(self):
        return f"{self.field}"

Alternatives

Additional Context

AttributeError: 'ForeignKey' object has no attribute 'rel'

When building Sphinx html docs with the plugin enabled I get this error:

Exception occurred:
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinxcontrib_django/docstrings.py", line 143, in _add_model_fields_as_params
    to = field.rel.to
AttributeError: 'ForeignKey' object has no attribute 'rel'

EDIT: Here is the full traceback

# Sphinx version: 1.6.6
# Python version: 3.5.2 (CPython)
# Docutils version: 0.14 
# Jinja2 version: 2.10
# Last messages:
#   updating environment:
#   
#   3 added, 0 changed, 0 removed
#   
#   reading sources... [ 33%] index
#   
#   reading sources... [ 66%] local-development
#   
#   reading sources... [100%] models
#   
# Loaded extensions:
#   alabaster (0.7.10) from /home/alex/.virtualenvs/gh/lib/python3.5/site-packages/alabaster/__init__.py
#   sphinxcontrib_django (unknown version) from /home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinxcontrib_django/__init__.py
#   sphinx.ext.autodoc (1.6.6) from /home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py
#   sphinx.ext.coverage (1.6.6) from /home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/coverage.py
Traceback (most recent call last):
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/cmdline.py", line 306, in main
    app.build(opts.force_all, filenames)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/application.py", line 339, in build
    self.builder.build_update()
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 329, in build_update
    'out of date' % len(to_build))
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 342, in build
    updated_docnames = set(self.env.update(self.config, self.srcdir, self.doctreedir))
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/environment/__init__.py", line 601, in update
    self._read_serial(docnames, self.app)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/environment/__init__.py", line 621, in _read_serial
    self.read_doc(docname, app)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/environment/__init__.py", line 758, in read_doc
    pub.publish()
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/core.py", line 217, in publish
    self.settings)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/io.py", line 74, in read
    self.parse()
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/readers/__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/__init__.py", line 191, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 171, in run
    input_source=document['source'])
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2753, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2326, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2338, in explicit_construct
    return method(self, expmatch)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2081, in directive
    directive_class, match, type_name, option_presets)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2130, in run_directive
    result = directive_instance.run()
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1843, in run
    documenter.generate(more_content=self.content)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1132, in generate
    self.document_members(all_members)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1053, in document_members
    check_module=members_check_module and not isattr)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1540, in generate
    all_members=all_members)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1129, in generate
    self.add_content(more_content)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1523, in add_content
    ModuleLevelDocumenter.add_content(self, more_content)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 846, in add_content
    for i, line in enumerate(self.process_doc(docstrings)):
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 806, in process_doc
    self.options, docstringlines)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/application.py", line 489, in emit
    return self.events.emit(event, self, *args)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinx/events.py", line 79, in emit
    results.append(callback(*args))
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinxcontrib_django/docstrings.py", line 101, in improve_model_docstring
    _improve_class_docs(app, obj, lines)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinxcontrib_django/docstrings.py", line 114, in _improve_class_docs
    _add_model_fields_as_params(app, cls, lines)
  File "/home/alex/.virtualenvs/gh/lib/python3.5/site-packages/sphinxcontrib_django/docstrings.py", line 143, in _add_model_fields_as_params
    to = field.rel.to
AttributeError: 'ForeignKey' object has no attribute 'rel'

option not to override Model field docstrings?

Documentation of my class members is ignored. Is there a way to configure to use provided docstrings, if present?

For example:

class CommonModel(models.Model):
    """
    Abstract :py:class:`~django.db.models.Model` with common fields for all "real" Models
    """
    #: globally unique id (UUID4)
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    #: date when this model instance becomes "active"
    effective_start_date = models.DateField(default=None, blank=True, null=True)
    #: date when this model instance becomes inactive
    effective_end_date = models.DateField(default=None, blank=True, null=True)
    #: who last modified this instance
    last_mod_user_name = models.CharField(default=None, null=True, max_length=80)
    #: when they modified it.
    last_mod_date = models.DateField(auto_now=True)

    class Meta:
        #: this is an abstract model
        abstract = True

When rendered with this package, it looks like this:


Parameters: * id (UUIDField) – Id
            * effective_start_date (DateField) -- Effective start date
            * effective_end_date (DateField) -- Effective end date
            * last_mod_user_name (CharField) -- Last mod user name
            * last_mod_date (DateField) -- Last mod date

id
Model field: id

effective_start_date
Model field: effective start date

...

without the package, like this (without the Parameters block and with the comments):

id
globally unique id (UUID4)

effective_start_date
date when this model instance becomes “active”

...

I've tried both with #: comments before and docstrings after each member.

I've also tried setting help_text which changes the Parameters display but not the members.
I have these autodoc settings in conf.py:

autodoc_member_order = 'bysource'
autodoc_inherit_docstrings = False

and I run apidoc like this: sphinx-apidoc -e -T -M -f -o apidoc ../myapp

And, unfortunately, if I don't use this package and don't document every member, I get this for each undocumented member:

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

So I really want to use this but want my docstrings to be used if present!

Merging of model field docstrings isn't rendering 2nd order directives

Hi, I'm trying to use this package in concert with another one that defines other directives (sphinx-needs).

I have a model field that has help text and its own docstring. This packages merges them as expected, but does not allow the directive in the previously-existing docstring to get rendered as a directive.

input:

    description = models.JSONField(
        blank=True,
        null=True,
        help_text="The detailed description of the requirement. Should be concise, singular, and written in the form of a 'shall'.",
    )
    """
    .. impl:: Store description as JSONField for richtext purposes
        :links: R_REQ_RICH_TEXT

    |
    """

Current result:

image

Desired result:

Something more like:
image
image

verbose_name is capitalized and goes against user expectations

In the following block in docstrings.py, .capitalize() is applied to the verbose_name.

    for field in obj._meta.get_fields():
        try:
            help_text = strip_tags(force_text(field.help_text))
            verbose_name = force_text(field.verbose_name).capitalize()
        except AttributeError:
            # e.g. ManyToOneRel
            continue

This is not behavior I expect as a user.

For example, I have a model and field:

class Configuration(models.Model):
    
    api_secret_key = models.CharField(
        max_length=32,
        blank=False,
        null=False,
        verbose_name='API Secret Key',
    )

I have explicitly set my preferred case (notably, all uppercase letters for the "API" abbreviation), but because .capitalize() is applied to verbose_name, this is turned into:

Api secret key


Solution proposals:

  • remove .capitalize() entirely (and update test cases)
  • add configuration option to enable or disable .capitalize()

I can't able to integrate properly

I'm trying to use this package in my project and curious about how this package works. but unfortunately i can't able to integrate this one. Here is my project structure

Screenshot_20200515_205241

By the way i generate docs folder using sphinx-quickstarter command

Add display name to field choices

Motivation

Right now when documenting a field with choices, the values of those choices are all that is included. This is frustrating because usually the display name of the choice documents what it means.

Proposed Solution

Add display names to choices documentation, i.e. change

f"* ``{key}``" if key != "" else "* ``''`` (Empty string)"
for key, value in field.choices[:choices_limit]

to

f"* ``{key}: {value}``" if key != "" else "* ``''`` (Empty string)"
for key, value in field.choices[:choices_limit]

in attributes.get_field_details (or something along those lines).

Extension interferes with other `autodoc-skip-member` event handlers

Any handler for the autodoc-skip-member signal should return None when the skipping behavior should not be changed:

If more than one enabled extension handles the autodoc-skip-member event, autodoc will use the first non-None value returned by a handler. Handlers should return None to fall back to the skipping behavior of autodoc and other enabled extensions.

At the moment, the value of skip is returned (which is True/False instead of None):

https://github.com/edoburu/sphinxcontrib-django/blob/471f23d3505f74bcff7bb1448781a85a3bc2bf8d/sphinxcontrib_django/docstrings/__init__.py#L147

Fields of django.forms.ModelForm not added

Form fields of forms which e.g. inherit from django.forms.ModelForm are not added to the docstring lines.
This is because in docstrings.py:118 only sub-classes of django.forms.Form are modified by _add_form_fields(). However, the inheritance path for model forms is:

django.forms.BaseForm ➡️ django.forms.models.BaseModelForm ➡️ django.forms.models.ModelForm

The corresponding test_add_form_fields does not catch this problem, because the test calls _add_form_fields() directly, whereas in the apidoc generation, improve_model_docstring() is called, which in turn calls _improve_class_docs() which contains the faulty check.

ForeignKeys on abstract models in Django >= 2.0 can break

If I have an abstract model with a ForeignKey specified as a string, I get the following error when generating Sphinx docs:

  File ".venv/lib/python3.6/site-packages/sphinxcontrib_django/docstrings.py", line 180, in _get_field_type
    field.name, type(field).__name__, to.__module__, to.__name__)
AttributeError: 'str' object has no attribute '__module__'

AttributeError: 'Sphinx' object has no attribute 'extensions'

Hello, I'm having an error while compiling the docs.
This error only occurs when I add sphinxcontrib-django to extensions.

I'm using Django 1.10 and sphinxcontrib-django 0.3.1.

extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.intersphinx',
    'sphinx.ext.todo',
    'sphinx.ext.coverage',
    'sphinx.ext.napoleon',
    'sphinx.ext.viewcode',
    'sphinx.ext.graphviz',
    'sphinx_autodoc_annotation',
    'sphinxcontrib_django',
]

Full traceback

# Sphinx version: 1.5.6
# Python version: 3.5.3 (CPython)
# Docutils version: 0.13.1 release
# Jinja2 version: 2.9.6
# Last messages:
#   WARNING: while setting up extension sphinx_autodoc_annotation: directive 'automethod' is already registered, it will be overridden
#   loading pickled environment...
#   done
#   building [mo]: targets for 0 po files that are out of date
#   building [html]: targets for 0 source files that are out of date
#   updating environment:
#   [extensions changed] 16 added, 0 changed, 0 removed
#   reading sources... [  6%] index
#   reading sources... [ 12%] modules/app
#   reading sources... [ 18%] modules/app1
# Loaded extensions:
#   sphinx.ext.coverage (1.5.6) from /home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/coverage.py
#   sphinx.ext.viewcode (1.5.6) from /home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/viewcode.py
#   sphinx_autodoc_annotation (unknown version) from /home/APP_DIR/lib/python3.5/site-packages/sphinx_autodoc_annotation.py
#   sphinx.ext.napoleon (1.5.6) from /home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/napoleon/__init__.py
#   sphinx.ext.todo (1.5.6) from /home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/todo.py
#   sphinx.ext.graphviz (1.5.6) from /home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/graphviz.py
#   sphinxcontrib_django (unknown version) from /home/APP_DIR/lib/python3.5/site-packages/sphinxcontrib_django/__init__.py
#   sphinx.ext.intersphinx (1.5.6) from /home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/intersphinx.py
#   alabaster (0.7.10) from /home/APP_DIR/lib/python3.5/site-packages/alabaster/__init__.py
#   sphinx.ext.autodoc (1.5.6) from /home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/autodoc.py
Traceback (most recent call last):
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/cmdline.py", line 296, in main
    app.build(opts.force_all, filenames)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/application.py", line 333, in build
    self.builder.build_update()
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 251, in build_update
    'out of date' % len(to_build))
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 265, in build
    self.doctreedir, self.app))
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/environment/__init__.py", line 556, in update
    self._read_serial(docnames, app)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/environment/__init__.py", line 576, in _read_serial
    self.read_doc(docname, app)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/environment/__init__.py", line 684, in read_doc
    pub.publish()
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/core.py", line 217, in publish
    self.settings)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/io.py", line 55, in read
    self.parse()
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/readers/__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/__init__.py", line 185, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 170, in run
    input_source=document['source'])
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2745, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 326, in section
    self.new_subsection(title, lineno, messages)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 394, in new_subsection
    node=section_node, match_titles=True)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    node=node, match_titles=match_titles)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 195, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2745, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 326, in section
    self.new_subsection(title, lineno, messages)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 394, in new_subsection
    node=section_node, match_titles=True)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    node=node, match_titles=match_titles)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 195, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2318, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2330, in explicit_construct
    return method(self, expmatch)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2073, in directive
    directive_class, match, type_name, option_presets)
  File "/home/APP_DIR/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2122, in run_directive
    result = directive_instance.run()
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1668, in run
    documenter.generate(more_content=self.content)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1013, in generate
    self.document_members(all_members)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 935, in document_members
    check_module=members_check_module and not isattr)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1010, in generate
    self.add_content(more_content)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 1383, in add_content
    ModuleLevelDocumenter.add_content(self, more_content)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 736, in add_content
    for i, line in enumerate(self.process_doc(docstrings)):
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/ext/autodoc.py", line 698, in process_doc
    self.options, docstringlines)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinx/application.py", line 589, in emit
    results.append(callback(self, *args))
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinxcontrib_django/docstrings.py", line 103, in improve_model_docstring
    _improve_class_docs(app, obj, lines)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinxcontrib_django/docstrings.py", line 116, in _improve_class_docs
    _add_model_fields_as_params(app, cls, lines)
  File "/home/APP_DIR/lib/python3.5/site-packages/sphinxcontrib_django/docstrings.py", line 146, in _add_model_fields_as_params
    if 'sphinx.ext.inheritance_diagram' in app.extensions and \
AttributeError: 'Sphinx' object has no attribute 'extensions'

Let me know if you need more information to debug!
Thanks

Deprecated function call

Description

Hi,

As of Django v.4.0 there is no longer force_text. It's now force_str

Django - Documentation: django.utils.encoding

Steps To Reproduce

  1. Create a Django 4.0 project
  2. Setup Sphinx with sphinxcontrib-django
  3. Try to generate documentation

Actual Behavior

Throws exception during DOC generation

Expected/Desired Behavior

Throws no exception during DOC generation

Screenshots

Exception

exception

Deprecated Code Snippet

force_text

ImportError: cannot import name 'available_attrs' from 'django.utils.decorators'

Hi

using django 3 I got this error launching migrate command:

File "/home//.virtualenvs//lib/python3.7/site-packages/django/urls/conf.py", line 34, in include urlconf_module = import_module(urlconf_module) File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1006, in _gcd_import File "<frozen importlib._bootstrap>", line 983, in _find_and_load File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 677, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 728, in exec_module File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed File "/home//.virtualenvs//lib/python3.7/site-packages/sphinxdoc/urls.py", line 7, in <module> from . import views File "/home//.virtualenvs//lib/python3.7/site-packages/sphinxdoc/views.py", line 20, in <module> from sphinxdoc.decorators import user_allowed_for_project File "/home//.virtualenvs//lib/python3.7/site-packages/sphinxdoc/decorators.py", line 7, in <module> from django.utils.decorators import available_attrs ImportError: cannot import name 'available_attrs' from 'django.utils.decorators' (/home//.virtualenvs//lib/python3.7/site-packages/django/utils/decorators.py)

Seems an issue with Django 3 as available_attrs seems not existing anymore. Can you have a look at it ?

Allow to override the docstrings for fields

If I have a simple model, and the verbose_name or help_text is public-facing and not what I'd like to see in my developer docs, I want to override the sphinxcontrib-django doc string by providing my own – but instead of overriding, I now have the same field documented twice.

(Bonus bug: the (SomeField) annotation provided by this package is found with the added to my additional documentation, not to the one generated by this package.)

Maintained Fork

Hello,
Since I didn't get a response on my PR #28, I decided to maintain and package my own fork of this project:

At this point in time, this fork provides the following additional features:

  • Support for current versions of Python and Django
  • Support for ModelForms
  • Support Intersphinx mappings to Django classes
  • 100% test coverage

If anyone wants to report issues and/or submit PRs which don't get addressed here, feel free to also submit them to my fork.

@vdboor I'd still be happy to merge my changes into the original repository, so if you're interested in PRs or me co-maintaining this project, let me know. If not, I'll probably detach my fork into an independent repository. In any case, many thanks for your work.

AttributeError: 'list' object has no attribute 'clear'

Getting this error when trying to build html:

Traceback (most recent call last): File "C:\Python27\lib\site-packages\sphinx\cmdline.py", line 304, in main app.build(args.force_all, filenames) File "C:\Python27\lib\site-packages\sphinx\application.py", line 331, in build self.builder.build_update() File "C:\Python27\lib\site-packages\sphinx\builders\__init__.py", line 333, in build_update 'out of date' % len(to_build)) File "C:\Python27\lib\site-packages\sphinx\builders\__init__.py", line 346, in build updated_docnames = set(self.env.update(self.config, self.srcdir, self.doctreedir)) File "C:\Python27\lib\site-packages\sphinx\environment\__init__.py", line 565, in update self._read_serial(docnames, self.app) File "C:\Python27\lib\site-packages\sphinx\environment\__init__.py", line 584, in _read_serial self.read_doc(docname, app) File "C:\Python27\lib\site-packages\sphinx\environment\__init__.py", line 659, in read_doc doctree = read_doc(self.app, self, self.doc2path(docname)) File "C:\Python27\lib\site-packages\sphinx\io.py", line 294, in read_doc pub.publish() File "C:\Python27\lib\site-packages\docutils\core.py", line 217, in publish self.settings) File "C:\Python27\lib\site-packages\docutils\readers\__init__.py", line 72, in read self.parse() File "C:\Python27\lib\site-packages\docutils\readers\__init__.py", line 78, in parse self.parser.parse(self.input, document) File "C:\Python27\lib\site-packages\sphinx\parsers.py", line 86, in parse self.statemachine.run(inputstring, document, inliner=self.inliner) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 171, in run input_source=document['source']) File "C:\Python27\lib\site-packages\docutils\statemachine.py", line 239, in run context, state, transitions) File "C:\Python27\lib\site-packages\docutils\statemachine.py", line 460, in check_line return method(match, context, next_state) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 2988, in text self.section(title.lstrip(), source, style, lineno + 1, messages) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section self.new_subsection(title, lineno, messages) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection node=section_node, match_titles=True) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse node=node, match_titles=match_titles) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run results = StateMachineWS.run(self, input_lines, input_offset) File "C:\Python27\lib\site-packages\docutils\statemachine.py", line 239, in run context, state, transitions) File "C:\Python27\lib\site-packages\docutils\statemachine.py", line 460, in check_line return method(match, context, next_state) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 2753, in underline self.section(title, source, style, lineno - 1, messages) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section self.new_subsection(title, lineno, messages) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection node=section_node, match_titles=True) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse node=node, match_titles=match_titles) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run results = StateMachineWS.run(self, input_lines, input_offset) File "C:\Python27\lib\site-packages\docutils\statemachine.py", line 239, in run context, state, transitions) File "C:\Python27\lib\site-packages\docutils\statemachine.py", line 460, in check_line return method(match, context, next_state) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 2326, in explicit_markup nodelist, blank_finish = self.explicit_construct(match) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 2338, in explicit_construct return method(self, expmatch) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 2081, in directive directive_class, match, type_name, option_presets) File "C:\Python27\lib\site-packages\docutils\parsers\rst\states.py", line 2130, in run_directive result = directive_instance.run() File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\directive.py", line 134, in run documenter.generate(more_content=self.content) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 793, in generate self.document_members(all_members) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 714, in document_members check_module=members_check_module and not isattr) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 1203, in generate all_members=all_members) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 793, in generate self.document_members(all_members) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 1192, in document_members ModuleLevelDocumenter.document_members(self, all_members) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 714, in document_members check_module=members_check_module and not isattr) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 790, in generate self.add_content(more_content) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 1391, in add_content ClassLevelDocumenter.add_content(self, more_content, no_docstring) File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 525, in add_content for i, line in enumerate(self.process_doc(docstrings)): File "C:\Python27\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 497, in process_doc self.options, docstringlines) File "C:\Python27\lib\site-packages\sphinx\application.py", line 444, in emit return self.events.emit(event, self, *args) File "C:\Python27\lib\site-packages\sphinx\events.py", line 79, in emit results.append(callback(*args)) File "C:\Python27\lib\site-packages\sphinxcontrib_django\docstrings.py", line 105, in improve_model_docstring _improve_attribute_docs(obj, name, lines) File "C:\Python27\lib\site-packages\sphinxcontrib_django\docstrings.py", line 212, in _improve_attribute_docs lines.clear() AttributeError: 'list' object has no attribute 'clear'

exception: 'str' object has no attribute '_meta' when GenericRelation

If you have a GenericRelation field that uses a deferred string argument rather than an a class argument, documentation build fails with:

Extension error (sphinxcontrib_django.docstrings):
Handler <function improve_docstring at 0x00000123AE286EE0> for event 'autodoc-process-docstring' threw an exception (exception: 'str' object has no attribute '_meta')

Through the debugger, I narrowed the issue down to here, where the format string argument fails because field.model is a string ("app2.ModelB" in the example code below)

https://github.com/edoburu/sphinxcontrib-django/blob/872cb8d56df8d76315a233ba8a2af3d9cce23b1c/sphinxcontrib_django/docstrings/field_utils.py#L83

Example code:

# in app1/models.py
class ModelA(models.Model):
    relation_field = GenericRelation(
        "app2.ModelB",
    )


# in app2/models.py
class ModelB(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField(null=True)
    content_object = GenericForeignKey()

I have a fix incoming that deals with this.

Unstable codecov workflow

The upload of the code coverage seems to be very unstable, I had to re-run the jobs multiple times today:

Error: Codecov: Failed to properly upload: The process '/Users/runner/work/_actions/codecov/codecov-action/v3/dist/codecov' failed with exit code 255

This seems to be related to this issue: codecov/codecov-action#598

One suggestion is to generate a secret token and use this despite the repo being public.

Unfortunately, we have a bottleneck here: @vdboor, you are the only person who can access the codecov administration settings since they manage the permissions per organization.

@vdboor would it be ok for you if I'd transfer ownership of this repository e.g. to the @jazzband organization to ensure maintenance in the long term?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.