Skip to content

Commit a9f7621

Browse files
committed
Add inline field docstrings to model doc
- Analyze model to get all attribute docstrings - Append the inline docstring of fields to their param documentation of the model
1 parent 4ca5b70 commit a9f7621

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Changelog
44
UNRELEASED
55
----------
66

7+
* Add inline docstrings of model fields to parameter documentation of models
78
* Add support for Python 3.11
89
* Add support for Django 4.1
910
* Drop support for Django 2.2

sphinxcontrib_django2/docstrings/classes.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from django import forms
66
from django.db import models
7+
from sphinx.pycode import ModuleAnalyzer
78

89
from .field_utils import get_field_type, get_field_verbose_name
910

@@ -81,22 +82,30 @@ def improve_model_docstring(app, model, lines):
8182
if field not in related_fields + reverse_related_fields
8283
]
8384

85+
# Analyze model to get inline field docstrings
86+
analyzer = ModuleAnalyzer.for_module(model.__module__)
87+
analyzer.analyze()
88+
field_docs = {
89+
field_name: ". " + " ".join(field_docstring).strip()
90+
for (_, field_name), field_docstring in analyzer.attr_docs.items()
91+
}
92+
8493
# Add the normal fields to the docstring
85-
add_model_parameters(non_related_fields, lines)
94+
add_model_parameters(non_related_fields, lines, field_docs)
8695

8796
# Add the related fields
8897
if related_fields:
8998
lines.append("")
9099
lines.append("Relationship fields:")
91100
lines.append("")
92-
add_model_parameters(related_fields, lines)
101+
add_model_parameters(related_fields, lines, field_docs)
93102

94103
# Add the reverse related fields
95104
if reverse_related_fields:
96105
lines.append("")
97106
lines.append("Reverse relationships:")
98107
lines.append("")
99-
add_model_parameters(reverse_related_fields, lines)
108+
add_model_parameters(reverse_related_fields, lines, field_docs)
100109

101110
# Add the inheritance diagram
102111
if (
@@ -107,7 +116,7 @@ def improve_model_docstring(app, model, lines):
107116
lines.append(".. inheritance-diagram::") # pragma: no cover
108117

109118

110-
def add_model_parameters(fields, lines):
119+
def add_model_parameters(fields, lines, field_docs):
111120
"""
112121
Add the given fields as model parameter with the ``:param:`` directive
113122
@@ -116,10 +125,14 @@ def add_model_parameters(fields, lines):
116125
117126
:param lines: The list of current docstring lines
118127
:type lines: list [ str ]
128+
129+
:param field_docs: The attribute docstrings of the model
130+
:type field_docs: dict
119131
"""
120132
for field in fields:
121-
# Add verbose name
122-
lines.append(f":param {field.name}: {get_field_verbose_name(field)}")
133+
# Add docstrings if they are found
134+
docstring = field_docs.get(field.name, "")
135+
lines.append(f":param {field.name}: {get_field_verbose_name(field)}{docstring}")
123136

124137
# Add type
125138
lines.append(f":type {field.name}: {get_field_type(field, include_role=False)}")

tests/test_class_docstrings.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,25 @@ def test_simple_model(app, do_autodoc):
1212
"",
1313
" :param id: Primary key: ID",
1414
" :type id: ~django.db.models.AutoField",
15-
" :param dummy_field: Very verbose name of dummy field. This should help you",
15+
" :param dummy_field: Very verbose name of dummy field. "
16+
"This should help you. Docstring of char field",
1617
" :type dummy_field: ~django.db.models.CharField",
1718
"",
1819
" Relationship fields:",
1920
"",
2021
" :param file: File "
21-
"(related name: :attr:`~dummy_django_app.models.FileModel.simple_models`)",
22+
"(related name: :attr:`~dummy_django_app.models.FileModel.simple_models`). "
23+
"Docstring of foreign key",
2224
" :type file: :class:`~django.db.models.ForeignKey` to "
2325
":class:`~dummy_django_app.models.FileModel`",
2426
" :param childA: ChildA "
25-
"(related name: :attr:`~dummy_django_app.models.ChildModelA.simple_model`)",
27+
"(related name: :attr:`~dummy_django_app.models.ChildModelA.simple_model`). "
28+
"Docstring of one to one field",
2629
" :type childA: :class:`~django.db.models.OneToOneField` to "
2730
":class:`~dummy_django_app.models.ChildModelA`",
2831
" :param childrenB: ChildrenB "
29-
"(related name: :attr:`~dummy_django_app.models.ChildModelB.simple_models`)",
32+
"(related name: :attr:`~dummy_django_app.models.ChildModelB.simple_models`). "
33+
"Docstring of many to many field",
3034
" :type childrenB: :class:`~django.db.models.ManyToManyField` to "
3135
":class:`~dummy_django_app.models.ChildModelB`",
3236
"",
@@ -59,21 +63,25 @@ def test_database_table(app, do_autodoc):
5963
"",
6064
" :param id: Primary key: ID",
6165
" :type id: ~django.db.models.AutoField",
62-
" :param dummy_field: Very verbose name of dummy field. This should help you",
66+
" :param dummy_field: Very verbose name of dummy field. "
67+
"This should help you. Docstring of char field",
6368
" :type dummy_field: ~django.db.models.CharField",
6469
"",
6570
" Relationship fields:",
6671
"",
6772
" :param file: File "
68-
"(related name: :attr:`~dummy_django_app.models.FileModel.simple_models`)",
73+
"(related name: :attr:`~dummy_django_app.models.FileModel.simple_models`). "
74+
"Docstring of foreign key",
6975
" :type file: :class:`~django.db.models.ForeignKey` to "
7076
":class:`~dummy_django_app.models.FileModel`",
7177
" :param childA: ChildA "
72-
"(related name: :attr:`~dummy_django_app.models.ChildModelA.simple_model`)",
78+
"(related name: :attr:`~dummy_django_app.models.ChildModelA.simple_model`). "
79+
"Docstring of one to one field",
7380
" :type childA: :class:`~django.db.models.OneToOneField` to "
7481
":class:`~dummy_django_app.models.ChildModelA`",
7582
" :param childrenB: ChildrenB "
76-
"(related name: :attr:`~dummy_django_app.models.ChildModelB.simple_models`)",
83+
"(related name: :attr:`~dummy_django_app.models.ChildModelB.simple_models`). "
84+
"Docstring of many to many field",
7785
" :type childrenB: :class:`~django.db.models.ManyToManyField` to "
7886
":class:`~dummy_django_app.models.ChildModelB`",
7987
"",

0 commit comments

Comments
 (0)