Merge pull request #2555 from hanhanhan/docs
|  | @ -4,42 +4,26 @@ Document | |||
| ========= | ||||
| 
 | ||||
| This project uses Sphinx_ documentation generator. | ||||
| After you have set up to `develop locally`_, run the following commands to generate the HTML documentation: :: | ||||
| 
 | ||||
|     $ sphinx-build docs/ docs/_build/html/ | ||||
| After you have set up to `develop locally`_, run the following command from the project directory to build and serve HTML documentation: :: | ||||
| 
 | ||||
|     $ make -C docs livehtml | ||||
| 
 | ||||
| If you set up your project to `develop locally with docker`_, run the following command: :: | ||||
| 
 | ||||
|     $ docker-compose -f local.yml run --rm django sphinx-build docs/ docs/_build/html/ | ||||
|     $ docker-compose -f local.yml up docs | ||||
| 
 | ||||
| Navigate to port 7000 on your host to see the documentation. This will be opened automatically at `localhost`_ for local, non-docker development. | ||||
| 
 | ||||
| Generate API documentation | ||||
| ---------------------------- | ||||
| 
 | ||||
| Sphinx can automatically generate documentation from docstrings, to enable this feature, follow these steps: | ||||
| Edit the docs/_source files and project application docstrings to create your documentation. | ||||
| 
 | ||||
| 1. Add Sphinx extension in ``docs/conf.py`` file, like below: :: | ||||
| 
 | ||||
|     extensions = [ | ||||
|         'sphinx.ext.autodoc', | ||||
|     ] | ||||
| 
 | ||||
| 2. Uncomment the following lines in the ``docs/conf.py`` file: :: | ||||
| 
 | ||||
|     # import django | ||||
|     # sys.path.insert(0, os.path.abspath('..')) | ||||
|     # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") | ||||
|     # django.setup() | ||||
| 
 | ||||
| 3. Run the following command: :: | ||||
| 
 | ||||
|     $ sphinx-apidoc -f -o ./docs/modules/ ./tpub/ migrations/* | ||||
| 
 | ||||
|    If you set up your project to `develop locally with docker`_, run the following command: :: | ||||
| 
 | ||||
|     $ docker-compose -f local.yml run --rm django sphinx-apidoc -f -o ./docs/modules ./tpub/ migrations/* | ||||
| 
 | ||||
| 4. Regenerate HTML documentation as written above. | ||||
| Sphinx can automatically include class and function signatures and docstrings in generated documentation.  | ||||
| See the generated project documentation for more examples. | ||||
| 
 | ||||
| .. _localhost: http://localhost:7000/ | ||||
| .. _Sphinx: https://www.sphinx-doc.org/en/master/index.html | ||||
| .. _develop locally: ./developing-locally.html | ||||
| .. _develop locally with docker: ./developing-locally-docker.html | ||||
|  |  | |||
							
								
								
									
										29
									
								
								{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,29 @@ | |||
| FROM python:3.8-slim-buster | ||||
| 
 | ||||
| ENV PYTHONUNBUFFERED 1 | ||||
| ENV PYTHONDONTWRITEBYTECODE 1 | ||||
| 
 | ||||
| RUN apt-get update \ | ||||
|     # dependencies for building Python packages | ||||
|     && apt-get install -y build-essential \ | ||||
|     # psycopg2 dependencies | ||||
|     && apt-get install -y libpq-dev \ | ||||
|     # Translations dependencies | ||||
|     && apt-get install -y gettext \ | ||||
|     # Uncomment below lines to enable Sphinx output to latex and pdf | ||||
|     # && apt-get install -y texlive-latex-recommended \ | ||||
|     # && apt-get install -y texlive-fonts-recommended \ | ||||
|     # && apt-get install -y texlive-latex-extra \ | ||||
|     # && apt-get install -y latexmk \ | ||||
|     # cleaning up unused files | ||||
|     && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
| 
 | ||||
| # Requirements are installed here to ensure they will be cached. | ||||
| COPY ./requirements /requirements | ||||
| # All imports needed for autodoc. | ||||
| RUN pip install -r /requirements/local.txt -r /requirements/production.txt | ||||
| 
 | ||||
| WORKDIR /docs | ||||
| 
 | ||||
| CMD make livehtml | ||||
|  | @ -4,17 +4,37 @@ | |||
| # You can set these variables from the command line, and also
 | ||||
| # from the environment for the first two.
 | ||||
| SPHINXOPTS    ?=  | ||||
| SPHINXBUILD   ?= sphinx-build | ||||
| SOURCEDIR     = . | ||||
| BUILDDIR      = _build | ||||
| SPHINXBUILD   ?= sphinx-build -c . | ||||
| SOURCEDIR     = ./_source | ||||
| BUILDDIR      = ./_build | ||||
| {%- if cookiecutter.use_docker == 'y' %} | ||||
| APP = /app | ||||
| {%- else %} | ||||
| APP = ../{{cookiecutter.project_slug}} | ||||
| {% endif %} | ||||
| 
 | ||||
| .PHONY: help livehtml apidocs Makefile | ||||
| 
 | ||||
| # Put it first so that "make" without argument is like "make help".
 | ||||
| help: | ||||
| 	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) | ||||
| 	@$(SPHINXBUILD) help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) | ||||
| 
 | ||||
| .PHONY: help Makefile | ||||
| # Build, watch and serve docs with live reload
 | ||||
| livehtml: | ||||
| 	sphinx-autobuild -b html  | ||||
| 	{%- if cookiecutter.use_docker == 'y' %} -H 0.0.0.0  | ||||
| 	{%- else %} --open-browser  | ||||
| 	{%- endif %} -p 7000 --watch $(APP) -c . $(SOURCEDIR) $(BUILDDIR)/html | ||||
| 
 | ||||
| # Outputs rst files from django application code
 | ||||
| apidocs: | ||||
| 	{%- if cookiecutter.use_docker == 'y' %} | ||||
| 	sphinx-apidoc -o $(SOURCEDIR)/api /app | ||||
| 	{%- else %} | ||||
| 	sphinx-apidoc -o $(SOURCEDIR)/api ../{{cookiecutter.project_slug}} | ||||
| 	{%- endif %} | ||||
| 
 | ||||
| # Catch-all target: route all unknown targets to Sphinx using the new
 | ||||
| # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
 | ||||
| %: Makefile | ||||
| 	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) | ||||
| 	@$(SPHINXBUILD) -b $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) | ||||
|  |  | |||
							
								
								
									
										46
									
								
								{{cookiecutter.project_slug}}/docs/_source/howto.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,46 @@ | |||
| How To - Project Documentation | ||||
| ====================================================================== | ||||
| 
 | ||||
| Get Started | ||||
| ---------------------------------------------------------------------- | ||||
| 
 | ||||
| Documentation can be written as rst files in the `{{cookiecutter.project_slug}}/docs/_source`. | ||||
| 
 | ||||
| {% if cookiecutter.use_docker == 'n' %} | ||||
| To build and serve docs, use the command: | ||||
|     :: | ||||
|      | ||||
|         make livehtml  | ||||
|      | ||||
| from inside the `{{cookiecutter.project_slug}}/docs` directory.  | ||||
| {% else %} | ||||
| To build and serve docs, use the commands: | ||||
|     :: | ||||
|      | ||||
|         docker-compose -f local.yml up docs | ||||
| {% endif %} | ||||
| 
 | ||||
| Changes to files in `docs/_source` will be picked up and reloaded automatically. | ||||
| 
 | ||||
| `Sphinx <https://www.sphinx-doc.org/>`_ is the tool used to build documentation. | ||||
| 
 | ||||
| Docstrings to Documentation | ||||
| ---------------------------------------------------------------------- | ||||
| 
 | ||||
| The sphinx extension `apidoc <https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html/>`_ is used to automatically document code using signatures and docstrings. | ||||
| 
 | ||||
| Numpy or Google style docstrings will be picked up from project files and availble for documentation. See the `Napoleon <https://sphinxcontrib-napoleon.readthedocs.io/en/latest/>`_ extension for details. | ||||
| 
 | ||||
| For an in-use example, see the `page source <_sources/users.rst.txt>`_ for :ref:`users`. | ||||
| 
 | ||||
| To compile all docstrings automatically into documentation source files, use the command: | ||||
|     :: | ||||
|      | ||||
|         make apidocs | ||||
| 
 | ||||
| {% if cookiecutter.use_docker == 'y' %} | ||||
| This can be done in the docker container: | ||||
|     ::  | ||||
|          | ||||
|         docker run --rm docs make apidocs | ||||
| {% endif -%} | ||||
|  | @ -10,7 +10,9 @@ Welcome to {{ cookiecutter.project_name }}'s documentation! | |||
|    :maxdepth: 2 | ||||
|    :caption: Contents: | ||||
| 
 | ||||
|    howto | ||||
|    pycharm/configuration | ||||
|    users | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB | 
| Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB | 
| Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 177 KiB | 
| Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB | 
| Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB | 
| Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB | 
| Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB | 
| Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 229 KiB | 
| Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 230 KiB | 
| Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB | 
| Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB | 
| Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										15
									
								
								{{cookiecutter.project_slug}}/docs/_source/users.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,15 @@ | |||
|  .. _users: | ||||
| 
 | ||||
| Users | ||||
| ====================================================================== | ||||
| 
 | ||||
| Starting a new project, it’s highly recommended to set up a custom user model,  | ||||
| even if the default User model is sufficient for you.  | ||||
| 
 | ||||
| This model behaves identically to the default user model,  | ||||
| but you’ll be able to customize it in the future if the need arises. | ||||
| 
 | ||||
| .. automodule:: {{cookiecutter.project_slug}}.users.models | ||||
|    :members: | ||||
|    :noindex: | ||||
| 
 | ||||
|  | @ -9,15 +9,19 @@ | |||
| # 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. | ||||
| # | ||||
| 
 | ||||
| import os | ||||
| import sys | ||||
| import django | ||||
| 
 | ||||
| # import django | ||||
| # sys.path.insert(0, os.path.abspath('..')) | ||||
| # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") | ||||
| # django.setup() | ||||
| 
 | ||||
| {% if cookiecutter.use_docker == 'y' %} | ||||
| sys.path.insert(0, os.path.abspath("/app")) | ||||
| os.environ.setdefault("DATABASE_URL", "") | ||||
| {% else %} | ||||
| sys.path.insert(0, os.path.abspath("..")) | ||||
| {%- endif %} | ||||
| os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") | ||||
| django.setup() | ||||
| 
 | ||||
| # -- Project information ----------------------------------------------------- | ||||
| 
 | ||||
|  | @ -31,17 +35,19 @@ author = "{{ cookiecutter.author_name }}" | |||
| # Add any Sphinx extension module names here, as strings. They can be | ||||
| # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom | ||||
| # ones. | ||||
| extensions = [] | ||||
| extensions = [ | ||||
|     "sphinx.ext.autodoc", | ||||
|     "sphinx.ext.napoleon", | ||||
| ] | ||||
| 
 | ||||
| # Add any paths that contain templates here, relative to this directory. | ||||
| templates_path = ["_templates"] | ||||
| # templates_path = ["_templates"] | ||||
| 
 | ||||
| # List of patterns, relative to source directory, that match files and | ||||
| # directories to ignore when looking for source files. | ||||
| # This pattern also affects html_static_path and html_extra_path. | ||||
| exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] | ||||
| 
 | ||||
| 
 | ||||
| # -- Options for HTML output ------------------------------------------------- | ||||
| 
 | ||||
| # The theme to use for HTML and HTML Help pages.  See the documentation for | ||||
|  | @ -52,4 +58,4 @@ html_theme = "alabaster" | |||
| # Add any paths that contain custom static files (such as style sheets) here, | ||||
| # relative to this directory. They are copied after the builtin static files, | ||||
| # so a file named "default.css" will overwrite the builtin "default.css". | ||||
| html_static_path = ["_static"] | ||||
| # html_static_path = ["_static"] | ||||
|  |  | |||
|  | @ -4,11 +4,13 @@ pushd %~dp0 | |||
| 
 | ||||
| REM Command file for Sphinx documentation | ||||
| 
 | ||||
| 
 | ||||
| if "%SPHINXBUILD%" == "" ( | ||||
| 	set SPHINXBUILD=sphinx-build | ||||
| 	set SPHINXBUILD=sphinx-build -c . | ||||
| ) | ||||
| set SOURCEDIR=. | ||||
| set SOURCEDIR=_source | ||||
| set BUILDDIR=_build | ||||
| set APP=..\{{cookiecutter.project_slug}} | ||||
| 
 | ||||
| if "%1" == "" goto help | ||||
| 
 | ||||
|  | @ -20,16 +22,25 @@ if errorlevel 9009 ( | |||
| 	echo.to the full path of the 'sphinx-build' executable. Alternatively you | ||||
| 	echo.may add the Sphinx directory to PATH. | ||||
| 	echo. | ||||
| 	echo.Install sphinx-autobuild for live serving. | ||||
| 	echo.If you don't have Sphinx installed, grab it from | ||||
| 	echo.http://sphinx-doc.org/ | ||||
| 	exit /b 1 | ||||
| ) | ||||
| 
 | ||||
| %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% | ||||
| %SPHINXBUILD% -b %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% | ||||
| goto end | ||||
| 
 | ||||
| :livehtml | ||||
| sphinx-autobuild -b html --open-browser -p 7000 --watch %APP% -c . %SOURCEDIR% %BUILDDIR%/html | ||||
| GOTO :EOF | ||||
| 
 | ||||
| :apidocs | ||||
| sphinx-apidoc -o %SOURCEDIR%/api %APP% | ||||
| GOTO :EOF | ||||
| 
 | ||||
| :help | ||||
| %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% | ||||
| %SPHINXBUILD% -b help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% | ||||
| 
 | ||||
| :end | ||||
| popd | ||||
|  |  | |||
|  | @ -36,6 +36,22 @@ services: | |||
|       - local_postgres_data_backups:/backups | ||||
|     env_file: | ||||
|       - ./.envs/.local/.postgres | ||||
| 
 | ||||
|   docs: | ||||
|     image: {{ cookiecutter.project_slug }}_local_docs | ||||
|     container_name: docs | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: ./compose/local/docs/Dockerfile | ||||
|     env_file: | ||||
|       - ./.envs/.local/.django | ||||
|     volumes: | ||||
|       - ./docs:/docs | ||||
|       - ./config:/app/config | ||||
|       - ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }} | ||||
|     ports: | ||||
|       - "7000:7000" | ||||
|      | ||||
|   {%- if cookiecutter.use_mailhog == 'y' %} | ||||
| 
 | ||||
|   mailhog: | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ | |||
| 
 | ||||
| Werkzeug==1.0.1 # https://github.com/pallets/werkzeug | ||||
| ipdb==0.13.3  # https://github.com/gotcha/ipdb | ||||
| Sphinx==3.1.1  # https://github.com/sphinx-doc/sphinx | ||||
| {%- if cookiecutter.use_docker == 'y' %} | ||||
| psycopg2==2.8.5 --no-binary psycopg2  # https://github.com/psycopg/psycopg2 | ||||
| {%- else %} | ||||
|  | @ -19,6 +18,11 @@ django-stubs==1.5.0  # https://github.com/typeddjango/django-stubs | |||
| pytest==5.4.3  # https://github.com/pytest-dev/pytest | ||||
| pytest-sugar==0.9.3  # https://github.com/Frozenball/pytest-sugar | ||||
| 
 | ||||
| # Documentation | ||||
| # ------------------------------------------------------------------------------ | ||||
| sphinx==3.1.1  # https://github.com/sphinx-doc/sphinx | ||||
| sphinx-autobuild # https://github.com/GaretJax/sphinx-autobuild | ||||
| 
 | ||||
| # Code quality | ||||
| # ------------------------------------------------------------------------------ | ||||
| flake8==3.8.3  # https://github.com/PyCQA/flake8 | ||||
|  |  | |||
|  | @ -5,10 +5,17 @@ from django.utils.translation import gettext_lazy as _ | |||
| 
 | ||||
| 
 | ||||
| class User(AbstractUser): | ||||
|     """Default user for {{cookiecutter.project_name}}. | ||||
|     """ | ||||
| 
 | ||||
|     # First Name and Last Name do not cover name patterns | ||||
|     # around the globe. | ||||
|     #: First and last name do not cover name patterns around the globe | ||||
|     name = CharField(_("Name of User"), blank=True, max_length=255) | ||||
| 
 | ||||
|     def get_absolute_url(self): | ||||
|         """Get url for user's detail view. | ||||
| 
 | ||||
|         Returns: | ||||
|             str: URL for user detail. | ||||
| 
 | ||||
|         """ | ||||
|         return reverse("users:detail", kwargs={"username": self.username}) | ||||
|  |  | |||