Skip to content

Commit

Permalink
Add reference and migration docs (#29)
Browse files Browse the repository at this point in the history
1. Enable RST references to Django and project code in Sphinx docs
2. Add reference documentation to the project
3. Document how to write data migrations with Improved User
4. Build documentation in Tox
5. Simplify Read Me; moves content to documentation
  • Loading branch information
jambonrose authored Aug 26, 2017
1 parent 791fb68 commit 6c98e3f
Show file tree
Hide file tree
Showing 24 changed files with 682 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--
Thank you for submitting a pull request (PR)! :tada::+1:
Thank you for submitting a pull request (PR)! 🎉👍
Remember that this is a volunteer-driven project. To help review your PR, please read the following guidelines.
Expand Down
3 changes: 3 additions & 0 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ request.
Please remember that this is a volunteer-driven project. We will look at
the issues and pull requests as soon as possible.

.. contents::
:local:

Code of Conduct
---------------

Expand Down
92 changes: 5 additions & 87 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,91 +56,9 @@ default by making a few modern and international changes.
* Replace :code:`first_name` and :code:`last_name` with international
friendly :code:`short_name` and :code:`full_name` fields

Installation
------------
For information about getting started, please refer to the `quickstart
documentation`_. For information about how to help with the project,
please see the `contributing documentation`_.

In a Terminal, use :code:`pip` to install the package from `PyPI`_.

.. code:: console
pip install django-improved-user
If you intend to use the ``UserFactory`` provided by the package to
allow for testing with |factory_boy|_, you can specify so during
install.

.. code:: console
pip install django-improved-user[factory]
If you do not but wish to use the :code:`UserFactory`, you will need to
install |factory_boy|_ yourself.

.. _PyPI: https://pypi.org
.. _factory_boy: https://github.com/FactoryBoy/factory_boy
.. |factory_boy| replace:: :code:`factory_boy`

Usage
-----

Perform the following steps in your ``settings.py`` file.

1. Add :code:`improved_user.apps.ImprovedUserConfig`
(or simply :code:`improved_user`) to :code:`INSTALLED_APPS`
2. Define or replace :code:`AUTH_USER_MODEL` with he new model, as
below.

.. code:: python
AUTH_USER_MODEL='improved_user.User'
3. In Django > 1.9, change :code:`UserAttributeSimilarityValidator` to
match correct :code:`User` fields, as shown below.

.. code:: python
AUTH_PREFIX = 'django.contrib.auth.password_validation.'
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': AUTH_PREFIX + 'UserAttributeSimilarityValidator',
'OPTIONS': {
'user_attributes': ('email', 'full_name', 'short_name')
},
},
# include other password validators here
]
Testing
-------

To run the test suite on a single version of Django (assuming you have a
version of Django installed), run the ``runtests.py`` script from the
root of the project.

.. code:: console
$ python runtests.py
You can limit the tests or pass paramaters as if you had called
``manage.py test``.

.. code:: console
$ ./runtests.py tests.test_basic -v 3
To run all linters and test multiple Python and Django versions, use
``tox``.

.. code:: console
$ tox
You will need to install Python 3.4, 3.5, and 3.6 on your system for
this to work.

You may also limit tests to specific environments or test suites with tox. For instance:

.. code:: console
$ tox -e py36-django111-unit tests.test_basic
$ tox -e py36-django111-integration user_integration.tests.TestViews.test_home
.. _contributing documentation: https://django-improved-user.readthedocs.io/en/development/contributing.html
.. _quickstart documentation: https://django-improved-user.readthedocs.io/en/development/quickstart.html
187 changes: 154 additions & 33 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,122 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Django Improved User documentation build configuration file, created by
# sphinx-quickstart on Thu Aug 17 10:44:16 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

# 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
# sys.path.insert(0, os.path.abspath('.'))
import sphinx_rtd_theme
"""Documentation Build Configuration
Django Improved User documentation build configuration file, created by
sphinx-quickstart on Thu Aug 17 10:44:16 2017.
This file is execfile()d with the current directory set to its
containing dir.
Note that not all possible configuration values are present in this
autogenerated file.
All configuration values have a default; values that are commented out
serve to show the default.
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 inspect
import sys
from operator import attrgetter
from os.path import abspath, join

import sphinx_rtd_theme # noqa: F401
from django import setup as django_setup
from django.conf import settings as django_settings
from django.utils.encoding import force_text
from django.utils.html import strip_tags

sys.path.insert(0, abspath(join('..', 'src')))
django_settings.configure(
INSTALLED_APPS=[
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'improved_user.apps.ImprovedUserConfig',
],
)
django_setup()


def annotate_field(lines, field, models):
if (not hasattr(field, 'verbose_name')
and not hasattr(field, 'help_text')):
return lines

if field.help_text:
# Decode and strip any html out of the field's help text
help_text = strip_tags(force_text(field.help_text))
else:
help_text = force_text(field.verbose_name).capitalize()
# Add the model field to the end of the docstring as a param
# using the verbose name as the description
lines.append(u':param %s: %s' % (field.attname, help_text))
# Add the field's type to the docstring
if isinstance(field, models.ForeignKey):
to = field.rel.to
lines.append(
u':type %s: %s to :class:`~%s.%s`'
% (field.attname,
type(field).__name__,
to.__module__,
to.__name__))
else:
lines.append(
u':type %s: %s'
% (field.attname, type(field).__name__))
return lines


def process_docstring(app, what, name, obj, options, lines):
# https://djangosnippets.org/snippets/2533/
# https://gist.github.com/abulka/48b54ea4cbc7eb014308
from django.db import models
from django.forms import BaseForm

if inspect.isclass(obj) and issubclass(obj, models.Model):
sorted_fields = sorted(obj._meta.get_fields(), key=attrgetter('name'))
primary_fields = [
field for field in sorted_fields if field.primary_key is True]
regular_fields = [
field for field in sorted_fields if field.primary_key is False]

for field in primary_fields:
lines = annotate_field(lines, field, models)

for field in regular_fields:
lines = annotate_field(lines, field, models)
elif inspect.isclass(obj) and issubclass(obj, BaseForm):
form = obj
for field_name in form.base_fields:
field = form.base_fields[field_name]
if field.help_text:
# Decode and strip any html out of the field's help text
help_text = strip_tags(force_text(field.help_text))
else:
help_text = force_text(field.label).capitalize()
lines.append(u':param %s: %s' % (field_name, help_text))
if field.widget.is_hidden:
lines.append(
u':type %s: (Hidden) %s'
% (field_name, type(field).__name__))
else:
lines.append(
u':type %s: %s'
% (field_name, type(field).__name__))

# Return the extended docstring
return lines


def setup(app):
# Register the docstring processor with sphinx
app.connect('autodoc-process-docstring', process_docstring)


# -- General configuration ------------------------------------------------
Expand All @@ -32,7 +128,18 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.viewcode']
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
]

intersphinx_mapping = {
'django': (
'http://docs.djangoproject.com/en/stable/',
'http://docs.djangoproject.com/en/stable/_objects/',
),
}

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Expand Down Expand Up @@ -110,7 +217,7 @@
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
'donate.html',
]
],
}


Expand Down Expand Up @@ -144,8 +251,13 @@
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'DjangoImprovedUser.tex', 'Django Improved User Documentation',
'Russell Keith-Magee, Andrew Pinkham', 'manual'),
(
master_doc,
'DjangoImprovedUser.tex',
'Django Improved User Documentation',
'Russell Keith-Magee, Andrew Pinkham',
'manual',
),
]


Expand All @@ -154,8 +266,13 @@
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'djangoimproveduser', 'Django Improved User Documentation',
[author], 1)
(
master_doc,
'djangoimproveduser',
'Django Improved User Documentation',
[author],
1,
),
]


Expand All @@ -165,10 +282,14 @@
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'DjangoImprovedUser', 'Django Improved User Documentation',
author, 'DjangoImprovedUser', 'One line description of project.',
'Miscellaneous'),
(
master_doc,
'DjangoImprovedUser',
'Django Improved User Documentation',
author,
'DjangoImprovedUser',
'A custom Django user that authenticates via email.' # no comma!
'Follows authentication best practices.',
'Miscellaneous',
),
]



Loading

0 comments on commit 6c98e3f

Please sign in to comment.