Commits

Michael Elsdörfer committed 90dd790 Merge

Merged with James Bennets upstream branch. This is a big merge, and some stuff is probably broken right now, many changes have been removed since they can now be implemented using the new backend.

Comments (0)

Files changed (62)

 *.pyc
 dist
 MANIFEST
+_build
+_static
 
 *.~*
+The primary author of django-registration is James Bennett
+<james@b-list.org>, who may be found online at
+<http://www.b-list.org/>.
+
+
+Others who have contributed to the application:
+
+* Samuel Adam (French translation)
+* Jannis Leidel (German translation)
+* Rapahel Hertzog (helpful suggestions on packaging and distribution)
+* Panos Laganakos (Greek translation)
+* Ilya Filippov and Andy Mikhailenko (Russian translation)
+* Jarek Zgoda (Polish translation)
+* Meir Kriheli (Hebrew translation)
+* Italo Maia (Brazilian Portuguese translation)
+* Shinya Okano (Japanese translation)
+* A. Al-Ibrahim (Arabic translation)
+* Ernesto Rico Schmidt (Spanish translation)
+* Vladislav Mitov (Bulgarian translation)
+* Leonardo Manuel Rocha (Argentinean Spanish translation)
+* Emil Stenström (Swedish translation)
+* Liang Feng (Chinese translations)
+* Nebojsa Djordjevic (Serbian translation)
+* Nicola Larosa (Italian translation)
+* Joost Cassee (Dutch translation)
+* Björn Kristinsson (Icelandic translation)
+* Rune Bromer (Danish translation)
+* Domen Kožar (Slovenian translation)
+* Young Gyu Park (Korean translation)

AUTHORS.txt

-The primary author of django-registration is James Bennett
-<james@b-list.org>, who may be found online at
-<http://www.b-list.org/>.
-
-
-Others who have contributed to the application:
-
-* Samuel Adam (French translation)
-* Jannis Leidel (German translation)
-* Rapahel Hertzog (helpful suggestions on packaging and distribution)
-* Panos Laganakos (Greek translation)
-* Ilya Filippov (Russian translation)
-* Jarek Zgoda (Polish translation)
-* Meir Kriheli (Hebrew translation)
-* Italo Maia (Brazilian Portuguese translation)
-* Shinya Okano (Japanese translation)
-* A. Al-Ibrahim (Arabic translation)
-* Ernesto Rico Schmidt (Spanish translation)
-* Vladislav Mitov (Bulgarian translation)
-* Leonardo Manuel Rocha (Argentinean Spanish translation)
-* Emil Stenström (Swedish translation)
-* Liang Feng (Chinese translations)
-* Nebojsa Djordjevic (Serbian translation)
-* Nicola Larosa (Italian translation)
-* Joost Cassee (Dutch translation)
+=============================
+django-registration changelog
+=============================
+
+
+Version 0.7, 6 November 2008:
+-----------------------------
+
+* Project hosting moved from Google Code to Bitbucket, and from a
+  Subversion repository to Mercurial.
+
+* Added test suite.
+
+* Full Django 1.0 compatibility.
+
+* Registration and activation views now accept an ``extra_context``
+  argument, identical to the way that argument works in Django's
+  generic views.
+
+* Added a custom management command for cleaning up expired
+  registrations; you can now run ``manage.py cleanupregistration`` to
+  handle this.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: The "username" field in
+  ``RegistrationForm`` is now a ``RegexField``.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: Removed the standalone script for
+  deleting expired user registrations; use the new management command
+  instead.
+
+
+Version 0.6, 29 July 2008:
+--------------------------
+
+* Packaged from revision 166 in Subversion.
+
+* Fixed a multiple-objects exception in
+  ``RegistrationFormUniqueEmail`` when multiple users already have the
+  same email address.
+
+* Changed the ``success_url`` of the ``register()`` view to use
+  reverse URL resolution.
+
+* Added an ``extra_context`` argument to the ``register`` and
+  ``activate`` views, mimicking its functionality in Django's generic
+  views.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: Switched the admin declaration to be
+  compliant with the newforms-admin refactor; the admin declaration
+  now lives in ``registration/admin.py``.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: Switched form imports from using
+  ``django.newforms`` to using ``django.forms``; the old style now
+  raises a deprecation warning on Django trunk and on Django 1.0
+  alpha.
+
+
+Version 0.5, 4 June 2008:
+-------------------------
+
+* Packaged from revision 155 in Subversion.
+
+* Added Serbian translation.
+
+* Added Italian translation.
+
+* Username/email uniqueness checks are now case-insensitive. This is
+  potentially backwards-incompatible if you relied on them being
+  case-sensitive, but I don't know of any reason why you'd be doing
+  that.
+
+* Included forms now use lazy translations.
+
+* The ``register`` view can now handle files submitted for use in form
+  processing.
+
+* Reactivation of a manually-deactivated account is now prevented by
+  changing the activation key, on successful activation, to a dummy
+  string which will fail on subsequent activation attempts.
+
+
+Version 0.4p2, 10 Feburary 2008:
+--------------------------------
+
+* Added Brazilian Portuguese translation.
+
+* Added Japanese translation.
+
+* Added Hebrew translation.
+
+* Minor documentation fixes.
+
+
+Version 0.4p1, 16 December 2007:
+--------------------------------
+
+* Packaged from revision 129 in Subversion.
+
+* Added Polish translation.
+
+
+Version 0.4, 8 December 2007:
+-----------------------------
+
+* Packaged from revision 122 in Subversion.
+
+* Added Greek translation.
+
+* Added Russian translation.
+
+* Changed ``maxlength`` to ``max_length`` now that Django issues a
+  deprecation warning for it.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: Changed the password validation to be
+  on ``clean()`` instead of ``clean_password2()``. This means that
+  errors from this must be accessed via ``non_field_errors()``.
+
+
+Version 0.3p5, 6 October 2007:
+------------------------------
+
+* Packaged from revision 112 in Subversion.
+
+* Added German translation.
+
+* Fixed a mismatch between the default ``RegistrationForm``'s maximum
+  length on email addresses and the actual maximum length on Django's
+  ``User`` model.
+
+* Fixed a situation where bad input for the ``password1`` field on
+  ``RegistrationForm`` could cause validation of ``password2`` to fail
+  with an exception.
+
+
+Version 0.3p4, 4 October 2007:
+------------------------------
+
+* Packaged from revision 101 in Subversion.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: In response to larger numbers of
+  complaints from people trying to use the example templates as-is,
+  the example templates have been removed.
+
+
+Version 0.3p2, 23 September 2007:
+---------------------------------
+
+* Packaged from revision 100 in Subversion.
+
+* Fixed ``activate`` view to actually take the ``template_name``
+  argument.
+
+
+Version 0.3p1, 22 September 2007:
+---------------------------------
+
+* Packaged from revision 99 in Subversion.
+
+* Fixed a typo in docs/overview.txt.
+
+* Fixed a typo in bin/delete_expired_users.py.
+
+* Added French translation.
+
+
+Version 0.3, 19 September 2007:
+-------------------------------
+
+Packaged from revision 89 in Subversion; download at
+http://django-registration.googlecode.com/files/registration-0.3.tar.gz
+
+* Changed ``register`` and ``activate`` views to accept
+  ``template_name`` keyword argument for selecting a custom template.
+
+* Changed ``register`` view to accept ``form_class`` keyword
+  argument specifying the form to use.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: Changed
+  ``RegistrationManager.create_inactive_user`` to use a template for
+  the subject of the activation email.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: Removed the ``tos`` field from
+  ``RegistrationForm``; if you were relying on it, switch to using
+  ``RegistrationFormTermsOfService`` instead.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: The activation email template now
+  receives the current ``Site`` object as the context variable
+  ``site``, and the ``current_site`` variable, which only held the
+  domain, is no longer available.
+
+* Added script ``bin/delete_expired_users.py`` with instructions on
+  how to use it as a cron job to clean up expired/inactive accounts.
+
+* Marked strings for translation and added ``locale`` directory so
+  that translations can be added.
+
+* Updated to deal with merge of Django's Unicode branch into trunk;
+  now using Unicode-aware functions everywhere.
+
+
+Version 0.2, 29 May 2007:
+-------------------------
+
+Packaged from revision 76 in Subversion; download at
+http://django-registration.googlecode.com/files/registration-0.2.tar.gz
+
+* Added ability to specify a callback in
+  ``RegistrationManager.create_inactive_user`` or in the ``register``
+  view to enable creation of site-specific user profile.
+
+* Separated out the logic of creating the profile into a new method on
+  ``RegistrationManager``: ``create_profile``.
+
+* Added URLConf support for various useful views in
+  ``django.contrib.auth``.
+
+* BACKWARDS-INCOMPATIBLE CHANGE: removed the ``key_generated`` field
+  from ``RegistrationProfile``; activation key expiration is now
+  calculated based on the ``date_joined`` field in the ``User`` model.
+  Drop the ``key_generated`` column from your database when upgrading
+  from 0.1.
+
+
+Version 0.1, 23 May 2007:
+-------------------------
+
+Packaged from revision 56 in Subversion; download at
+http://django-registration.googlecode.com/files/registration-0.1.tar.gz
+
+* First packaged version using distutils.
+
+* Added docs/ directory and overview. 

CHANGELOG.txt

-=============================
-django-registration changelog
-=============================
-
-
-Version 0.7, 6 November 2008:
------------------------------
-
-* Project hosting moved from Google Code to Bitbucket, and from a
-  Subversion repository to Mercurial.
-
-* Added test suite.
-
-* Full Django 1.0 compatibility.
-
-* Registration and activation views now accept an ``extra_context``
-  argument, identical to the way that argument works in Django's
-  generic views.
-
-* Added a custom management command for cleaning up expired
-  registrations; you can now run ``manage.py cleanupregistration`` to
-  handle this.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: The "username" field in
-  ``RegistrationForm`` is now a ``RegexField``.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: Removed the standalone script for
-  deleting expired user registrations; use the new management command
-  instead.
-
-
-Version 0.6, 29 July 2008:
---------------------------
-
-* Packaged from revision 166 in Subversion.
-
-* Fixed a multiple-objects exception in
-  ``RegistrationFormUniqueEmail`` when multiple users already have the
-  same email address.
-
-* Changed the ``success_url`` of the ``register()`` view to use
-  reverse URL resolution.
-
-* Added an ``extra_context`` argument to the ``register`` and
-  ``activate`` views, mimicking its functionality in Django's generic
-  views.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: Switched the admin declaration to be
-  compliant with the newforms-admin refactor; the admin declaration
-  now lives in ``registration/admin.py``.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: Switched form imports from using
-  ``django.newforms`` to using ``django.forms``; the old style now
-  raises a deprecation warning on Django trunk and on Django 1.0
-  alpha.
-
-
-Version 0.5, 4 June 2008:
--------------------------
-
-* Packaged from revision 155 in Subversion.
-
-* Added Serbian translation.
-
-* Added Italian translation.
-
-* Username/email uniqueness checks are now case-insensitive. This is
-  potentially backwards-incompatible if you relied on them being
-  case-sensitive, but I don't know of any reason why you'd be doing
-  that.
-
-* Included forms now use lazy translations.
-
-* The ``register`` view can now handle files submitted for use in form
-  processing.
-
-* Reactivation of a manually-deactivated account is now prevented by
-  changing the activation key, on successful activation, to a dummy
-  string which will fail on subsequent activation attempts.
-
-
-Version 0.4p2, 10 Feburary 2008:
---------------------------------
-
-* Added Brazilian Portuguese translation.
-
-* Added Japanese translation.
-
-* Added Hebrew translation.
-
-* Minor documentation fixes.
-
-
-Version 0.4p1, 16 December 2007:
---------------------------------
-
-* Packaged from revision 129 in Subversion.
-
-* Added Polish translation.
-
-
-Version 0.4, 8 December 2007:
------------------------------
-
-* Packaged from revision 122 in Subversion.
-
-* Added Greek translation.
-
-* Added Russian translation.
-
-* Changed ``maxlength`` to ``max_length`` now that Django issues a
-  deprecation warning for it.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: Changed the password validation to be
-  on ``clean()`` instead of ``clean_password2()``. This means that
-  errors from this must be accessed via ``non_field_errors()``.
-
-
-Version 0.3p5, 6 October 2007:
-------------------------------
-
-* Packaged from revision 112 in Subversion.
-
-* Added German translation.
-
-* Fixed a mismatch between the default ``RegistrationForm``'s maximum
-  length on email addresses and the actual maximum length on Django's
-  ``User`` model.
-
-* Fixed a situation where bad input for the ``password1`` field on
-  ``RegistrationForm`` could cause validation of ``password2`` to fail
-  with an exception.
-
-
-Version 0.3p4, 4 October 2007:
-------------------------------
-
-* Packaged from revision 101 in Subversion.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: In response to larger numbers of
-  complaints from people trying to use the example templates as-is,
-  the example templates have been removed.
-
-
-Version 0.3p2, 23 September 2007:
----------------------------------
-
-* Packaged from revision 100 in Subversion.
-
-* Fixed ``activate`` view to actually take the ``template_name``
-  argument.
-
-
-Version 0.3p1, 22 September 2007:
----------------------------------
-
-* Packaged from revision 99 in Subversion.
-
-* Fixed a typo in docs/overview.txt.
-
-* Fixed a typo in bin/delete_expired_users.py.
-
-* Added French translation.
-
-
-Version 0.3, 19 September 2007:
--------------------------------
-
-Packaged from revision 89 in Subversion; download at
-http://django-registration.googlecode.com/files/registration-0.3.tar.gz
-
-* Changed ``register`` and ``activate`` views to accept
-  ``template_name`` keyword argument for selecting a custom template.
-
-* Changed ``register`` view to accept ``form_class`` keyword
-  argument specifying the form to use.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: Changed
-  ``RegistrationManager.create_inactive_user`` to use a template for
-  the subject of the activation email.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: Removed the ``tos`` field from
-  ``RegistrationForm``; if you were relying on it, switch to using
-  ``RegistrationFormTermsOfService`` instead.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: The activation email template now
-  receives the current ``Site`` object as the context variable
-  ``site``, and the ``current_site`` variable, which only held the
-  domain, is no longer available.
-
-* Added script ``bin/delete_expired_users.py`` with instructions on
-  how to use it as a cron job to clean up expired/inactive accounts.
-
-* Marked strings for translation and added ``locale`` directory so
-  that translations can be added.
-
-* Updated to deal with merge of Django's Unicode branch into trunk;
-  now using Unicode-aware functions everywhere.
-
-
-Version 0.2, 29 May 2007:
--------------------------
-
-Packaged from revision 76 in Subversion; download at
-http://django-registration.googlecode.com/files/registration-0.2.tar.gz
-
-* Added ability to specify a callback in
-  ``RegistrationManager.create_inactive_user`` or in the ``register``
-  view to enable creation of site-specific user profile.
-
-* Separated out the logic of creating the profile into a new method on
-  ``RegistrationManager``: ``create_profile``.
-
-* Added URLConf support for various useful views in
-  ``django.contrib.auth``.
-
-* BACKWARDS-INCOMPATIBLE CHANGE: removed the ``key_generated`` field
-  from ``RegistrationProfile``; activation key expiration is now
-  calculated based on the ``date_joined`` field in the ``User`` model.
-  Drop the ``key_generated`` column from your database when upgrading
-  from 0.1.
-
-
-Version 0.1, 23 May 2007:
--------------------------
-
-Packaged from revision 56 in Subversion; download at
-http://django-registration.googlecode.com/files/registration-0.1.tar.gz
-
-* First packaged version using distutils.
-
-* Added docs/ directory and overview. 
+Thanks for downloading django-registration.
+
+To install it, run the following command inside this directory:
+
+    python setup.py install
+
+If you have the Python ``easy_install`` utility available, you can
+also type the following to download and install in one step::
+
+   easy_install django-registration
+
+Or if you're using ``pip``::
+
+    pip install django-registration
+
+Or if you'd prefer you can simply place the included ``registration``
+directory somewhere on your Python path, or symlink to it from
+somewhere on your Python path; this is useful if you're working from a
+Mercurial checkout.
+
+Note that this application requires Python 2.3 or later, and a
+functional installation of Django 1.` or newer. You can obtain Python
+from http://www.python.org/ and Django from
+http://www.djangoproject.com/.

INSTALL.txt

-Thanks for downloading django-registration.
-
-To install it, run the following command inside this directory:
-
-    python setup.py install
-
-If you have the Python ``easy_install`` utility available, you can
-also type the following to download and install in one step::
-
-   easy_install django-registration
-
-Or if you're using ``pip``::
-
-    pip install django-registration
-
-Or if you'd prefer you can simply place the included ``registration``
-directory somewhere on your Python path, or symlink to it from
-somewhere on your Python path; this is useful if you're working from a
-Mercurial checkout.
-
-Note that this application requires Python 2.3 or later, and a
-functional installation of Django 1.0 or newer. You can obtain Python
-from http://www.python.org/ and Django from
-http://www.djangoproject.com/.
+Copyright (c) 2007-2009, James Bennett
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of the author nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

LICENSE.txt

-Copyright (c) 2007-2008, James Bennett
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of the author nor the names of other
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-include CHANGELOG.txt
-include INSTALL.txt
-include LICENSE.txt
+include CHANGELOG
+include INSTALL
+include LICENSE
 include MANIFEST.in
-include README.txt
-include AUTHORS.txt
+include README
+include AUTHORS
 recursive-include docs *
-recursive-include registration/bin *
 recursive-include registration/locale *
+========================
+Django user registration
+========================
+
+This is a fairly simple user-registration application for Django_,
+designed to make allowing user signups as painless as possible. It
+requires a functional installation of Django 1.1 or newer, but has no
+other dependencies.
+
+For installation instructions, see the file "INSTALL" in this
+directory; for instructions on how to use this application, and on
+what it provides, see the file "quickstart.rst" in the "docs/"
+directory.

README.txt

-========================
-Django user registration
-========================
-
-This is a fairly simple user-registration application for Django_,
-designed to make allowing user signups as painless as possible. It
-requires a functional installation of Django 1.0 or newer, but has no
-other dependencies.
-
-For installation instructions, see the file "INSTALL.txt" in this
-directory; for instructions on how to use this application, and on
-what it provides, see the file "overview.txt" in the "docs/"
-directory.
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  dirhtml   to make HTML files named index.html in directories"
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  qthelp    to make HTML files and a qthelp project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf _build/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
+	@echo
+	@echo "Build finished. The HTML pages are in _build/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in _build/dirhtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in _build/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in _build/qthelp, like this:"
+	@echo "# qcollectiongenerator _build/qthelp/django-registration.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile _build/qthelp/django-registration.qhc"
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in _build/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
+	@echo
+	@echo "The overview file is in _build/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in _build/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in _build/doctest/output.txt."

docs/backend-api.rst

+.. _backend-api:
+
+User registration backends
+==========================
+
+At its core, django-registration is built around the idea of pluggable
+backends which can implement different workflows for user
+registration. Although :ref:`the default backend <default-backend>`
+uses a common two-phase system (registration followed by activation),
+backends are generally free to implement any workflow desired by their
+authors.
+
+This is deliberately meant to be complementary to Django's own
+`pluggable authentication backends
+<http://docs.djangoproject.com/en/dev/topics/auth/#other-authentication-sources>`_;
+a site which uses an OpenID authentication backend, for example, can
+and should make use of a registration backend which handles signups
+via OpenID. And, like a Django authentication backend, a registration
+backend is simply a class which implements a particular standard API
+(described below).
+
+This allows for a great deal of flexibility in the actual workflow of
+registration; backends can, for example, implement any of the
+following (not an exhaustive list):
+
+* One-step (register, and done) or multi-step (register and activate)
+  signup.
+
+* Invitation-based registration.
+
+* Selectively allowing or disallowing registration (e.g., by requiring
+  particular credentials to register).
+
+* Enabling/disabling registration entirely.
+
+* Registering via sources other than a standard username/password,
+  such as OpenID.
+
+* Selective customization of the registration process (e.g., using
+  different forms or imposing different requirements for different
+  types of users).
+
+
+Specifying the backend to use
+-----------------------------
+
+To determine which backend to use, the :ref:`views in
+django-registration <views>` accept a keyword argument ``backend``; in
+all cases, this should be a string containing the full dotted Python
+import path to the backend class to be used. So, for example, to use
+the default backend, you'd pass the string
+``'registration.backends.default.DefaultBackend'`` as the value of the
+``backend`` argument (and the default URLconf included with that
+backend does so). The specified backend class will then be imported
+and instantiated (by calling its constructor with no arguments), and
+the resulting instance will be used for all backend-specific
+functionality.
+
+If the specified backend class cannot be imported, django-registration
+will raise ``django.core.exceptions.ImproperlyConfigured``.
+
+
+Backend API
+-----------
+
+To be used as a registration backend, a class must implement the
+following methods. For many cases, subclassing the default backend and
+selectively overriding behavior will be suitable, but for other
+situations (e.g., workflows significantly different from the default)
+a full implementation is needed.
+
+
+register(request, \*\*kwargs)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This method implements the logic of actually creating the new user
+account. Often, but not necessarily always, this will involve creating
+an instance of ``django.contrib.auth.models.User`` from the supplied
+data.
+
+This method will only be called after a signup form has been
+displayed, and the data collected by the form has been properly
+validated.
+
+Arguments to this method are:
+
+``request``
+    The Django `HttpRequest
+    <http://docs.djangoproject.com/en/dev/ref/request-response/#httprequest-objects>`_
+    object in which a new user is attempting to register.
+
+``**kwargs``
+    A dictionary of the ``cleaned_data`` from the signup form.
+
+After creating the new user account, this method should create or
+obtain an instance of ``django.contrib.auth.models.User`` representing
+that account. It should then send the signal
+:data:`registration.signals.user_registered`, with three arguments:
+
+``sender``
+    The backend class (e.g., ``self.__class__``).
+
+``user``
+    The ``User`` instance representing the new account.
+
+``request``
+    The ``HttpRequest`` in which the user registered.
+
+Finally, this method should return the ``User`` instance.
+
+
+activate(request, \*\*kwargs)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For workflows which require a separate activation step, this method
+should implement the necessary logic for account activation.
+
+Arguments to this method are:
+
+``request``
+    The Django ``HttpRequest`` object in which the account is being
+    activated.
+
+``**kwargs``
+    A dictionary of any additional arguments (e.g., information
+    captured from the URL, such as an activation key) received by the
+    :func:`~registration.views.activate` view. The combination of the
+    ``HttpRequest`` and this additional information must be sufficient
+    to identify the account which will be activated.
+
+If the account cannot be successfully activated (for example, in the
+default backend if the activation period has expired), this method
+should return ``False``.
+
+If the account is successfully activated, this method should create or
+obtain an instance of ``django.contrib.auth.models.User`` representing
+the activated account. It should then send the signal
+:data:`registration.signals.user_activated`, with three arguments:
+
+``sender``
+    The backend class.
+
+``user``
+    The ``User`` instance representing the activated account.
+
+``request``
+    The ``HttpRequest`` in which the user activated.
+
+This method should then return the ``User`` instance.
+
+For workflows which do not require a separate activation step, this
+method can and should raise ``NotImplementedError``.
+
+
+registration_allowed(request)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This method returns a boolean value indicating whether the given
+``HttpRequest`` is permitted to register a new account (``True`` if
+registration is permitted, ``False`` otherwise). It may determine this
+based on some aspect of the ``HttpRequest`` (e.g., the presence or
+absence of an invitation code in the URL), based on a setting (in the
+default backend, a setting can be used to disable registration),
+information in the database or any other information it can access.
+
+Arguments to this method are:
+
+``request``
+    The Django ``HttpRequest`` object in which a new user is
+    attempting to register.
+
+If this method returns ``False``, the
+:func:`~registration.views.register` view will not display a form for
+account creation; instead, it will issue a redirect to a URL
+explaining that registration is not permitted.
+
+
+get_form_class(request)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This method should return a form class -- a subclass of
+``django.forms.Form`` -- suitable for use in registering users with
+this backend. As such, it should collect and validate any information
+required by the backend's ``register`` method.
+
+Arguments to this method are:
+
+``request``
+    The Django ``HttpRequest`` object in which a new user is
+    attempting to register.
+
+
+post_registration_redirect(request, user)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This method should return a location to which the user will be
+redirected after successful registration. This should be a tuple of
+``(to, args, kwargs)``, suitable for use as the arguments to `Django's
+"redirect" shortcut
+<http://docs.djangoproject.com/en/dev/topics/http/shortcuts/#redirect>`_.
+
+Arguments to this method are:
+
+``request``
+    The Django ``HttpRequest`` object in which the user registered.
+
+``user``
+    The ``User`` instance representing the new user account.
+
+
+post_activation_redirect(request, user)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For workflows which require a separate activation step, this method
+should return a location to which the user will be redirected after
+successful activation.  This should be a tuple of ``(to, args,
+kwargs)``, suitable for use as the arguments to `Django's "redirect"
+shortcut
+<http://docs.djangoproject.com/en/dev/topics/http/shortcuts/#redirect>`_.
+
+Arguments to this method are:
+
+``request``
+    The Django ``HttpRequest`` object in which the user activated.
+
+``user``
+    The ``User`` instance representing the activated user account.
+
+For workflows which do not require a separate activation step, this
+method can and should raise ``NotImplementedError``.
+# -*- coding: utf-8 -*-
+#
+# django-registration documentation build configuration file, created by
+# sphinx-quickstart on Mon Jun 22 02:57:42 2009.
+#
+# 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.
+
+import sys, os
+
+# 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.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'django-registration'
+copyright = u'2009, James Bennett'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.8'
+# The full version, including alpha/beta/rc tags.
+release = '0.8'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# 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']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'django-registrationdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'django-registration.tex', u'django-registration Documentation',
+   u'James Bennett', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True

docs/default-backend.rst

+.. _default-backend:
+.. module:: registration.backends.default
+
+The default backend
+===================
+
+A default :ref:`registration backend <backend-api>` is bundled with
+django-registration, as the class
+``registration.backends.default.DefaultBackend``, and implements a
+simple two-step workflow in which a new user first registers, then
+confirms and activates the new account by following a link sent to the
+email address supplied during registration.
+
+
+Default behavior and configuration
+----------------------------------
+
+This backend makes use of the following settings:
+
+``ACCOUNT_ACTIVATION_DAYS``
+    This is the number of days users will have to activate their
+    accounts after registering. Failing to activate during that period
+    will leave the account inactive (and possibly subject to
+    deletion). This setting is required, and must be an integer.
+
+``REGISTRATION_OPEN``
+    A boolean (either ``True`` or ``False``) indicating whether
+    registration of new accounts is currently permitted. This setting
+    is optional, and a default of ``True`` will be assumed if it is
+    not supplied.
+
+By default, this backend uses
+:class:`registration.forms.RegistrationForm` as its form class for
+user registration; this can be overridden by passing the keyword
+argument ``form_class`` to the :func:`~registration.views.register`
+view.
+
+Upon successful registration -- not activation -- the default redirect
+is to the URL pattern named ``registration_complete``; this can be
+overridden by passing the keyword argument ``success_url`` to the
+:func:`~registration.views.register` view.
+
+Upon successful activation, the default redirect is to the URL pattern
+named ``registration_activation_complete``; this can be overridden by
+passing the keyword argument ``success_url`` to the
+:func:`~registration.views.activate` view.
+
+
+How account data is stored for activation
+-----------------------------------------
+
+During registration, a new instance of
+``django.contrib.auth.models.User`` is created to represent the new
+account, with the ``is_active`` field set to ``False``. An email is
+then sent to the email address of the account, containing a link the
+user must click to activate the account; at that point the
+``is_active`` field is set to ``True``, and the user may log in
+normally.
+
+Activation is handled by generating and storing an activation key in
+the database, using the following model:
+
+
+.. currentmodule:: registration.models
+
+.. class:: RegistrationProfile
+
+   A simple representation of the information needed to activate a new
+   user account. This is **not** a user profile; it simply provides a
+   place to temporarily store the activation key and determine whether
+   a given account has been activated.
+
+   Has the following fields:
+
+   .. attribute:: user
+
+      A ``ForeignKey`` to ``django.contrib.auth.models.User``,
+      representing the user account for which activation information
+      is being stored.
+
+   .. attribute:: activation_key
+
+      A 40-character ``CharField``, storing the activation key for the
+      account. Initially, the activation key is the hexdigest of a
+      SHA1 hash; after activation, this is reset to :attr:`ACTIVATED`.
+
+   Additionally, one class attribute exists:
+
+   .. attribute:: ACTIVATED
+
+      A constant string used as the value of :attr:`activation_key`
+      for accounts which have been activated.
+
+   And the following methods:
+
+   .. method:: activation_key_expired()
+
+      Determines whether this account's activation key has expired,
+      and returns a boolean (``True`` if expired, ``False``
+      otherwise). Uses the following algorithm:
+
+      1. If :attr:`activation_key` is :attr:`ACTIVATED`, the account
+         has already been activated and so the key is considered to
+         have expired.
+
+      2. Otherwise, the date of registration (obtained from the
+         ``date_joined`` field of :attr:`user`) is compared to the
+         current date; if the span between them is greater than the
+         value of the setting ``ACCOUNT_ACTIVATION_DAYS``, the key is
+         considered to have expired.
+
+      :rtype: bool
+
+   .. method:: send_activation_email(site)
+
+      Sends an activation email to the address of the account.
+
+      The activation email will make use of two templates:
+      ``registration/activation_email_subject.txt`` and
+      ``registration/activation_email.txt``, which are used for the
+      subject of the email and the body of the email,
+      respectively. Each will receive the following context:
+
+      ``activation_key``
+          The value of :attr:`activation_key`.
+
+      ``expiration_days``
+          The number of days the user has to activate, taken from the
+          setting ``ACCOUNT_ACTIVATION_DAYS``.
+
+      ``site``
+          An object representing the site on which the account was
+          registered; depending on whether ``django.contrib.sites`` is
+          installed, this may be an instance of either
+          ``django.contrib.sites.models.Site`` (if the sites
+          application is installed) or
+          ``django.contrib.sites.models.RequestSite`` (if
+          not). Consult `the documentation for the Django sites
+          framework
+          <http://docs.djangoproject.com/en/dev/ref/contrib/sites/>`_
+          for details regarding these objects' interfaces.
+
+      Because email subjects must be a single line of text, the
+      rendered output of ``registration/activation_email_subject.txt``
+      will be forcibly condensed to a single line.
+
+      :param site: An object representing the site on which account
+         was registered.
+      :type site: ``django.contrib.sites.models.Site`` or
+        ``django.contrib.sites.models.RequestSite``
+      :rtype: ``None``
+
+
+Additionally, :class:`RegistrationProfile` has a custom manager
+(accessed as ``RegistrationProfile.objects``):
+
+
+.. class:: RegistrationManager
+
+   This manager provides several convenience methods for creating and
+   working with instances of :class:`RegistrationProfile`:
+
+   .. method:: activate_user(activation_key)
+
+      Validates ``activation_key`` and, if valid, activates the
+      associated account by setting its ``is_active`` field to
+      ``True``. To prevent re-activation of accounts, the
+      :attr:`~RegistrationProfile.activation_key` of the
+      :class:`RegistrationProfile` for the account will be set to
+      :attr:`RegistrationProfile.ACTIVATED` after successful
+      activation.
+
+      Returns the ``User`` instance representing the account if
+      activation is successful, ``False`` otherwise.
+
+      :param activation_key: The activation key to use for the
+         activation.
+      :type activation_key: string, a 40-character SHA1 hexdigest
+      :rtype: ``User`` or bool
+
+   .. method:: delete_expired_users
+
+      Removes expired instances of :class:`RegistrationProfile`, and
+      their associated user accounts, from the database. This is
+      useful as a periodic maintenance task to clean out accounts
+      which registered but never activated.
+
+      Accounts to be deleted are identified by searching for instances
+      of :class:`RegistrationProfile` with expired activation keys and
+      with associated user accounts which are inactive (have their
+      ``is_active`` field set to ``False``). To disable a user account
+      without having it deleted, simply delete its associated
+      :class:`RegistrationProfile`; any ``User`` which does not have
+      an associated :class:`RegistrationProfile` will not be deleted.
+
+      A custom management command is provided which will execute this
+      method, suitable for use in cron jobs or other scheduled
+      maintenance tasks: ``manage.py cleanupregistration``.
+
+      :rtype: ``None``
+
+   .. method:: create_inactive_user(username, email, password, site[, send_email])
+
+      Creates a new, inactive user account and an associated instance
+      of :class:`RegistrationProfile`, sends the activation email and
+      returns the new ``User`` object representing the account.
+
+      :param username: The username to use for the new account.
+      :type username: string
+      :param email: The email address to use for the new account.
+      :type email: string
+      :param password: The password to use for the new account.
+      :type password: string
+      :param site: An object representing the site on which the
+         account is being registered.
+      :type site: ``django.contrib.sites.models.Site`` or
+         ``django.contrib.sites.models.RequestSite``
+      :param send_email: If ``True``, the activation email will be
+         sent to the account (by calling
+         :meth:`RegistrationProfile.send_activation_email`). If
+         ``False``, no email will be sent (but the account will still
+         be inactive)
+      :type send_email: bool
+      :rtype: ``User``
+
+   .. method:: create_profile(user)
+
+      Creates and returns a :class:`RegistrationProfile` instance for
+      the account represented by ``user``.
+
+      The ``RegistrationProfile`` created by this method will have its
+      :attr:`~RegistrationProfile.activation_key` set to a SHA1 hash
+      generated from a combination of the account's username and a
+      random salt.
+
+      :param user: The user account; an instance of
+         ``django.contrib.auth.models.User``.
+      :type user: ``User``
+      :rtype: ``RegistrationProfile``
+.. _faq:
+
+Frequently-asked questions
+==========================
+
+The following are miscellaneous common questions and answers related
+to installing/using django-registration, culled from bug reports,
+emails and other sources.
+
+
+General
+-------
+
+**What license is django-registration under?**
+    django-registration is offered under a three-clause BSD-style
+    license; this is `an OSI-approved open-source license
+    <http://www.opensource.org/licenses/bsd-license.php>`_, and allows
+    you a large degree of freedom in modifiying and redistributing the
+    code. For the full terms, see the file ``LICENSE`` which came with
+    your copy of django-registration; if you did not receive a copy of
+    this file, you can view it online at
+    <http://bitbucket.org/ubernostrum/django-registration/src/tip/LICENSE>.
+
+**Why are the forms and models for the default backend not in the default backend?**
+    The model and manager used by :ref:`the default backend
+    <default-backend>` are in ``registration.models``, and the default
+    form class (and various subclasses) are in ``registration.forms``;
+    logically, they might be expected to exist in
+    ``registration.backends.default``, but there are several reasons
+    why that's not such a good idea:
+
+    1. Older versions of django-registration made use of the model and
+       form classes, and moving them would create an unnecessary
+       backwards incompatibility: ``import`` statements would need to
+       be changed, and some database updates would be needed to
+       reflect the new location of the
+       :class:`~registration.models.RegistrationProfile` model.
+
+    2. Due to the design of Django's ORM, the ``RegistrationProfile``
+       model would end up with an ``app_label`` of ``default``, which
+       isn't particularly descriptive and may conflict with other
+       applications. By keeping it in ``registration.models``, it
+       retains an ``app_label`` of ``registration``, which more
+       accurately reflects what it does and is less likely to cause
+       problems.
+
+    3. Although the ``RegistrationProfile`` model and the various
+       :ref:`form classes <forms>` are used by the default backend,
+       they can and are meant to be reused as needed by other
+       backends. Any backend which uses an activation step should feel
+       free to reuse the ``RegistrationProfile`` model, for example,
+       and the registration form classes are in no way tied to a
+       specific backend (and cover a number of common use cases which
+       will crop up regardless of the specific backend logic in use).
+
+
+Installation and setup
+----------------------
+
+**How do I install django-registration?**
+    Full instructions are available in :ref:`the quick start guide <quickstart>`.
+
+**Do I need to put a copy of django-registration in every project I use it in?**
+    No; putting applications in your project directory is a very bad
+    habit, and you should stop doing it. If you followed the
+    instructions mentioned above, django-registration was installed
+    into a location that's on your Python import path, so you'll only
+    ever need to add ``registration`` to your ``INSTALLED_APPS``
+    setting (in any project, or in any number of projects), and it
+    will work.
+
+**Does django-registration come with any sample templates I can use right away?**
+    No, for two reasons:
+
+    1. Providing default templates with an application is generally
+       hard to impossible, because different sites can have such
+       wildly different design and template structure. Any attempt to
+       provide templates which would work with all the possibilities
+       would probably end up working with none of them.
+
+    2. A number of things in django-registration depend on the
+       specific :ref:`registration backend <backend-api>` you use,
+       including the variables which end up in template
+       contexts. Since django-registration has no way of knowing in
+       advance what backend you're going to be using, it also has no
+       way of knowing what your templates will need to look like.
+    
+    Fortunately, however, django-registration has good documentation
+    which explains what context variables will be available to
+    templates, and so it should be easy for anyone who knows Django's
+    template system to create templates which integrate with their own
+    site.
+
+
+Configuration
+-------------
+
+**Do I need to rewrite the views to change the way they behave?**
+    No. There are several ways you can customize behavior without
+    making any changes whatsoever:
+
+    * Pass custom arguments -- e.g., to specify forms, template names,
+      etc. -- to :ref:`the registration views <views>`.
+
+    * Use the :ref:`signals <signals>` sent by the views to add custom
+      behavior.
+
+    * Write a custom :ref:`registration backend <backend-api>` which
+      implements the behavior you need, and have the views use your
+      backend.
+
+    If none of these are sufficient, your best option is likely to
+    simply write your own views; however, it is hoped that the level
+    of customization exposed by these options will be sufficient for
+    nearly all user-registration workflows.
+
+**How do I pass custom arguments to the views?**
+    Part 3 of the official Django tutorial, when it `introduces
+    generic views
+    <http://docs.djangoproject.com/en/dev/intro/tutorial04/#use-generic-views-less-code-is-better>`_,
+    covers the necessary mechanism: simply provide a dictionary of
+    keyword arguments in your URLconf.
+
+**Does that mean I should rewrite django-registration's default URLconf?**
+    No; if you'd like to pass custom arguments to the registration
+    views, simply write and include your own URLconf instead of
+    including the default one provided with django-registration.
+
+**I don't want to write my own URLconf because I don't want to write patterns for all the auth views!**
+    You're in luck, then; django-registration provides a URLconf which
+    *only* contains the patterns for the auth views, and which you can
+    include in your own URLconf anywhere you'd like; it lives at
+    ``registration.auth_urls``.
+
+**I don't like the names you've given to the URL patterns!**
+    In that case, you should feel free to set up your own URLconf
+    which uses the names you want.
+
+
+Troubleshooting
+---------------
+
+**I've got functions listening for the registration/activation signals, but they're not getting called!**
+
+    The most common cause of this is placing django-registration in a
+    sub-directory that's on your Python import path, rather than
+    installing it directly onto the import path as normal. Importing
+    from django-registration in that case can cause various issues,
+    including incorrectly connecting signal handlers. For example, if
+    you were to place django-registration inside a directory named
+    ``django_apps``, and refer to it in that manner, you would end up
+    with a situation where your code does this::
+
+        from django_apps.registration.signals import user_registered
+
+    But django-registration will be doing::
+
+        from registration.signals import user_registered
+
+    From Python's point of view, these import statements refer to two
+    different objects in two different modules, and so signal handlers
+    connected to the signal from the first import will not be called
+    when the signal is sent using the second import.
+
+    To avoid this problem, follow the standard practice of installing
+    django-registration directly on your import path and always
+    referring to it by its own module name: ``registration`` (and in
+    general, it is always a good idea to follow normal Python
+    practices for installing and using Django applications).
+
+
+Tips and tricks
+---------------
+
+**How do I log a user in immediately after registration or activation?**
+    You can most likely do this simply by writing a function which
+    listens for the appropriate :ref:`signal <signals>`; your function
+    should set the ``backend`` attribute of the user to the correct
+    authentication backend, and then call
+    ``django.contrib.auth.login()`` to log the user in.
+
+**How do I re-send an activation email?**
+    Assuming you're using :ref:`the default backend
+    <default-backend>`, a `custom admin action
+    <http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/>`_
+    is provided for this; in the admin for the
+    :class:`~registration.models.RegistrationProfile` model, simply
+    click the checkbox for the user(s) you'd like to re-send the email
+    for, then select the "Re-send activation emails" action.
+
+**How do I manually activate a user?**
+    In the default backend, a custom admin action is provided for
+    this. In the admin for the ``RegistrationProfile`` model, click
+    the checkbox for the user(s) you'd like to activate, then select
+    the "Activate users" action.
+.. _forms:
+.. module:: registration.forms
+
+Forms for user registration
+===========================
+
+Several form classes are provided with django-registration, covering
+common cases for gathering account information and implementing common
+constraints for user registration. These forms were designed with
+django-registration's :ref:`default backend <default-backend>` in
+mind, but may also be useful in other situations.
+
+
+.. class:: RegistrationForm
+
+   A simple form for registering an account. Has the following fields,
+   all of which are required:
+
+   ``username``
+       The username to use for the new account. This is represented as
+       a text input which validates that the username is unique,
+       consists entirely of alphanumeric characters and underscores
+       and is at most 30 characters in length.
+
+   ``email``
+      The email address to use for the new account. This is
+      represented as a text input which accepts email addresses up to
+      75 characters in length.
+
+   ``password1``
+      The password to use for the new account. This represented as a
+      password input (``input type="password"`` in the rendered HTML).
+
+   ``password2``
+      The password to use for the new account. This represented as a
+      password input (``input type="password"`` in the rendered HTML).
+
+   The constraints on usernames and email addresses match those
+   enforced by Django's default authentication backend for instances
+   of ``django.contrib.auth.models.User``. The repeated entry of the
+   password serves to catch typos.
+
+   Because it does not apply to any single field of the form, the
+   validation error for mismatched passwords is attached to the form
+   itself, and so must be accessed via the form's
+   ``non_field_errors()`` method.
+
+
+.. class:: RegistrationFormTermsOfService
+
+   A subclass of :class:`RegistrationForm` which adds one additional,
+   required field:
+
+   ``tos``
+       A checkbox indicating agreement to the site's terms of
+       service/user agreement.
+
+
+.. class:: RegistrationFormUniqueEmail
+
+   A subclass of :class:`RegistrationForm` which enforces uniqueness
+   of email addresses in addition to uniqueness of usernames.
+
+
+.. class:: RegistrationFormNoFreeEmail
+
+   A subclass of :class:`RegistrationForm` which disallows
+   registration using addresses from some common free email
+   providers. This can, in some cases, cut down on automated
+   registration by spambots.
+
+   By default, the following domains are disallowed for email
+   addresses:
+
+   * ``aim.com``
+
+   * ``aol.com``
+
+   * ``email.com``
+
+   * ``gmail.com``
+
+   * ``googlemail.com``
+
+   * ``hotmail.com``
+
+   * ``hushmail.com``
+
+   * ``msn.com``
+
+   * ``mail.ru``
+
+   * ``mailinator.com``
+
+   * ``live.com``
+
+   * ``yahoo.com``
+
+   To change this, subclass this form and set the class attribute
+   ``bad_domains`` to a list of domains you wish to disallow.

docs/forms.txt

-=====
-Forms
-=====
-
-
-To ease and automate the process of validating user information during
-registration, several form classes (built using Django's `forms
-library`_) are provided: a base ``RegistrationForm`` and subclasses
-which provide specific customized functionality. All of the forms
-described below are found in ``registration.forms``.
-
-.. _forms library: http://docs.djangoproject.com/en/dev/topics/forms/
-
-
-``RegistrationForm``
-====================
-
-Form for registering a new user account.
-
-Validates that the requested username is not already in use, and
-requires the password to be entered twice to catch typos.
-
-Subclasses should feel free to add any additional validation they
-need, but should either preserve the base ``save()`` or implement a
-``save()`` method which returns a ``User``.
-    
-Fields:
-
-``username``
-    The new user's requested username. Will be validated according to
-    the same regular expression Django's authentication system uses to
-    validate usernames.
-
-``email``
-    The new user's email address. Must be a well-formed email address.
-
-``password1``
-    The new user's password.
-
-``password2``
-    The password, again, to catch typos.
-
-
-Non-validation methods:
-
-``save()``
-    Creates the new ``User`` and ``RegistrationProfile``, and returns
-    the ``User`` (by calling
-    ``RegistrationProfile.objects.create_inactive_user()``).
-
-
-Subclasses of ``RegistrationForm``
-==================================
-
-As explained above, subclasses may add any additional validation they
-like, but must either preserve the ``save()`` method or implement a
-``save()`` method with an identical signature.
-
-Three subclasses are included as examples, and as ready-made
-implementations of useful customizations:
-
-``RegistrationFormTermsOfService``
-    Subclass of ``RegistrationForm`` which adds a required checkbox
-    for agreeing to a site's Terms of Service.
-
-``RegistrationFormUniqueEmail``
-    Subclass of ``RegistrationForm`` which enforces uniqueness of
-    email addresses.
-
-``RegistrationFormNoFreeEmail``
-    Subclass of ``RegistrationForm`` which disallows registration with
-    email addresses from popular free webmail services; moderately
-    useful for preventing automated spam registrations.
-    
-    To change the list of banned domains, subclass this form and
-    override the attribute ``bad_domains``.
+.. django-registration documentation master file, created by
+   sphinx-quickstart on Mon Jun 22 02:57:42 2009.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+django-registration 0.8 documentation
+=====================================
+
+This documentation covers the 0.8 release of django-registration, a
+simple but extensible application providing user registration
+functionality for `Django <http://www.djangoproject.com>`_-powered
+websites.
+
+Although nearly all aspects of the registration process are
+customizable, the default setup of django-registration attempts to
+cover the most common use case: two-phase registration, consisting of
+initial signup followed by a confirmation email which contains
+instructions for activating the new account.
+
+To get up and running quickly, consult the :ref:`quick-start guide
+<quickstart>`, which describes all the necessary steps to install
+django-registration and configure it for the default workflow. For
+more detailed information, including how to customize the registration
+process (including support for alternate registration systems), read
+through the documentation listed below.
+
+If you are upgrading from a previous release, please read the
+:ref:`upgrade guide <upgrade>` for information on what's changed.
+
+Contents:
+
+.. toctree::
+   :maxdepth: 1
+   
+   quickstart
+   release-notes
+   upgrade
+   backend-api
+   default-backend
+   forms
+   views
+   signals
+   faq
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+set SPHINXBUILD=sphinx-build
+set ALLSPHINXOPTS=-d _build/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html      to make standalone HTML files
+	echo.  dirhtml   to make HTML files named index.html in directories
+	echo.  pickle    to make pickle files
+	echo.  json      to make JSON files
+	echo.  htmlhelp  to make HTML files and a HTML help project
+	echo.  qthelp    to make HTML files and a qthelp project
+	echo.  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  changes   to make an overview over all changed/added/deprecated items
+	echo.  linkcheck to check all external links for integrity
+	echo.  doctest   to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (_build\*) do rmdir /q /s %%i
+	del /q /s _build\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% _build/html
+	echo.
+	echo.Build finished. The HTML pages are in _build/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% _build/dirhtml
+	echo.
+	echo.Build finished. The HTML pages are in _build/dirhtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% _build/pickle
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% _build/json
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% _build/htmlhelp
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in _build/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% _build/qthelp
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in _build/qthelp, like this:
+	echo.^> qcollectiongenerator _build\qthelp\django-registration.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile _build\qthelp\django-registration.ghc
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% _build/latex
+	echo.
+	echo.Build finished; the LaTeX files are in _build/latex.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% _build/changes
+	echo.
+	echo.The overview file is in _build/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% _build/linkcheck
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in _build/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% _build/doctest
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in _build/doctest/output.txt.
+	goto end
+)
+
+:end

docs/models.txt

-===================
-Models and managers
-===================
-
-
-Because the two-step process of registration and activation requires
-some means of temporarily storing activation key and retrieving it for
-verification, a simple model --
-``registration.models.RegistrationProfile`` -- is provided in this
-application, and a custom manager --
-``registration.models.RegistrationManager`` -- is included and defines
-several useful methods for interacting with ``RegistrationProfile``.
-
-Both the ``RegistrationProfile`` model and the ``RegistrationManager``
-are found in ``registration.models``.
-
-
-The ``RegistrationProfile`` model
-=================================
-
-A simple profile which stores an activation key for use during user
-account registration.
-
-Generally, you will not want to interact directly with instances of
-this model; the provided manager includes methods for creating and
-activating new accounts, as well as for cleaning out accounts which
-have never been activated.
-
-While it is possible to use this model as the value of the
-``AUTH_PROFILE_MODULE`` setting, it's not recommended that you do
-so. This model's sole purpose is to store data temporarily during
-account registration and activation, and a mechanism for automatically
-creating an instance of a site-specific profile model is provided via
-the ``create_inactive_user`` on ``RegistrationManager``.
-    
-``RegistrationProfile`` objects have the following fields:
-
-``activation_key``
-    A SHA1 hash used as an account's activation key.
-
-``user``
-    The ``User`` object for which activation information is being
-    stored.
-
-``RegistrationProfile`` also has one custom method defined:
-
-``activation_key_expired()``
-    Determines whether this ``RegistrationProfile``'s activation key
-    has expired.
-    
-    Returns ``True`` if the key has expired, ``False`` otherwise.
-    
-    Key expiration is determined by a two-step process:
-    
-    1. If the user has already activated, the key will have been reset
-       to the string constant ``ACTIVATED``. Re-activating is not
-       permitted, and so this method returns ``True`` in this case.
-    
-    2. Otherwise, the date the user signed up is incremented by the
-       number of days specified in the setting
-       ``ACCOUNT_ACTIVATION_DAYS`` (which should be the number of days
-       after signup during which a user is allowed to activate their
-       account); if the result is less than or equal to the current
-       date, the key has expired and this method returns ``True``.
-
-
-The ``RegistrationManager``
-===========================
-
-Custom manager for the ``RegistrationProfile`` model.
-    
-The methods defined here provide shortcuts for account creation and
-activation (including generation and emailing of activation keys), and
-for cleaning out expired inactive accounts.
-    
-Methods:
-
-``activate_user(activation_key)``
-    Validate an activation key and activate the corresponding
-    ``User`` if valid.
-    
-    If the key is valid and has not expired, return the ``User``
-    after activating.
-    
-    If the key is not valid or has expired, return ``False``.
-    
-    If the key is valid but the ``User`` is already active,
-    return ``False``.
-    
-    To prevent reactivation of an account which has been
-    deactivated by site administrators, the activation key is
-    reset to the string constant ``RegistrationProfile.ACTIVATED``
-    after successful activation.
-
-    To execute customized logic when a ``User`` is activated,
-    connect a function to the signal
-    ``registration.signals.user_activated``; this signal will be
-    sent (with the ``User`` as the value of the keyword argument
-    ``user``) after a successful activation.
-
-``create_inactive_user(username, password, email, send_email=True)``
-    Create a new, inactive ``User``, generate a
-    ``RegistrationProfile`` and email its activation key to the
-    ``User``, returning the new ``User``.
-    
-    To disable the email, call with ``send_email=False``.
-
-    The activation email will make use of two templates:
-
-    ``registration/activation_email_subject.txt``
-        This template will be used for the subject line of the
-        email. It receives one context variable, ``site``, which
-        is the currently-active
-        ``django.contrib.sites.models.Site`` instance. Because it
-        is used as the subject line of an email, this template's
-        output **must** be only a single line of text; output
-        longer than one line will be forcibly joined into only a
-        single line.
-
-    ``registration/activation_email.txt``
-        This template will be used for the body of the email. It
-        will receive three context variables: ``activation_key``
-        will be the user's activation key (for use in constructing
-        a URL to activate the account), ``expiration_days`` will
-        be the number of days for which the key will be valid and
-        ``site`` will be the currently-active
-        ``django.contrib.sites.models.Site`` instance.
-
-    To execute customized logic once the new ``User`` has been
-    created, connect a function to the signal
-    ``registration.signals.user_registered``; this signal will be
-    sent (with the new ``User`` as the value of the keyword
-    argument ``user``) after the ``User`` and
-    ``RegistrationProfile`` have been created, and after the email (if
-    any) has been sent.
-        
-``create_profile(user)``
-    Creates a ``RegistrationProfile`` for a given ``User``. Returns
-    the ``RegistrationProfile``.
-    
-    The activation key for the ``RegistrationProfile`` will be a SHA1
-    hash, generated from a combination of the ``User``'s username and
-    a random salt.
-
-``deleted_expired_users()``
-    Removes expired instances of ``RegistrationProfile`` and their
-    associated ``User`` objects.
-    
-    Accounts to be deleted are identified by searching for instances
-    of ``RegistrationProfile`` with expired activation keys, and then
-    checking to see if their associated ``User`` instances have the
-    field ``is_active`` set to ``False``; any ``User`` who is both
-    inactive and has an expired activation key will be deleted.
-    
-    It is recommended that this method be executed regularly as part
-    of your routine site maintenance; this application provides a