django-registration-plus / registration / views.py

"""
Views which allow users to create and validate accounts.

"""
from django.contrib.auth.decorators import login_required

from django.shortcuts import redirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _

from registration.backends import get_backend
from registration.backends.invitational import UserAlreadyExists, InvitationException
from registration.models import RegistrationInvitation


def invite(request, backend, success_url=None, form_class=None,
           template_name='registration/invitation_form.html',
           extra_context=None):
    """
    Allow an existing user to invite new users.
    
    The actual invitation will be delegated to the backend specified by the 
    ``backend`` keyword argument (see below); it will be used as follows:
    
    1. The form to use for user invitation will be obtained by calling the 
       backend's ``get_invitation_form_class()`` method, passing the 
       ``HttpRequest``. To override this, see the list of optional arguments 
       for this view (below). On GET requests, the form is initialized with 
       request.GET as initial_data.
    
    2. If valid, the form's ``cleaned_data`` will be passed (as keyword 
       arguments, and along with the ``HttpRequest``) to the backend's 
       ``invite()`` method, which should return the new 
       ``RegistrationInvitation`` object.
    
    3. Upon successful invitation, the backend's ``post_invitation_redirect()`` 
       method will be called, passing the ``HttpRequest`` and the new 
       ``RegistrationInvitation``, to determine the URL to redirect the user 
       to. To override this, see the list of optional arguments for this view 
       (below).
    
    **Required arguments**
    
    ``backend``
        The dotted Python import path to the backend class to use.
    
    **Optional arguments**
    
    ``success_url``
        URL to redirect to after successful invitation. Must be a value which 
        can legally be passed to ``django.shortcuts.redirect``. If not 
        supplied, this will be retrieved from the backend.
    
    ``form_class``
        The form class to use for invitation. If not supplied, this will be 
        retrieved from the backend.
    
    ``template_name``
        A custom template to use. If not supplied, this will default to 
        ``registration/registration_form.html``.
    
    ``extra_context``
        A dictionary of variables to add to the template context. Any callable 
        object in this dictionary will be called to produce the end result 
        which appears in the context.
    
    **Context:**
    
    ``form``
        The invitation form.
    
    ``error``
        The error message when invitation fails.
    
    Any extra variables supplied in the ``extra_context`` argument (see above).
    
    **Template:**
    
    registration/registration_form.html or ``template_name`` keyword argument.
    
    """
    backend = get_backend(backend)
    if form_class is None:
        form_class = backend.get_invitation_form_class(request)
    
    error = ''
    if not RegistrationInvitation.objects.has_invitations(request.user):
        error = _("You have no invitations left to send.")
    
    if request.method == 'POST':
        form = form_class(data=request.POST, files=request.FILES)
        if form.is_valid():
            try:
                invitation = backend.invite(request, **form.cleaned_data)
                if invitation:
                    if success_url is None:
                        to, args, kwargs = backend.post_invitation_redirect(request, invitation)
                        return redirect(to, *args, **kwargs)
                    else:
                        return redirect(success_url)
                else:
                    error = _("Sending the invitation failed.")
            except InvitationException, ex:
                error = unicode(ex)
    else:
        form = form_class(initial=request.GET)
    
    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = value() if callable(value) else value
    
    return render_to_response(template_name, 
                              {'form': form, 'error': error}, 
                              context_instance=context)
invite = login_required(invite)

def register(request, backend, success_url=None,
             disallowed_url='registration_disallowed',
             template_name='registration/registration_form.html',
             extra_context=None, form_class=None):
    """
    Allow a new user to register an account.
    
    The actual registration of the account will be delegated to the backend 
    specified by the ``backend`` keyword argument (see below); it will be used 
    as follows:
    
    1. The backend's ``registration_allowed()`` method will be called, passing 
       the ``HttpRequest``, to determine whether registration of an account is 
       to be allowed; if not, a redirect is issued to the view corresponding to 
       the named URL pattern ``registration_disallowed``. To override this, see 
       the list of optional arguments for this view (below).
    
    2. The form to use for account registration will be obtained by calling the 
       backend's ``get_form_class()`` method, passing the ``HttpRequest``. To 
       override this, see the list of optional arguments for this view (below).
    
    3. If valid, the form's ``cleaned_data`` will be passed (as keyword 
       arguments, and along with the ``HttpRequest``) to the backend's 
       ``register()`` method, which should return the new ``User`` object.
    
    4. Upon successful registration, the backend's 
       ``post_registration_redirect()`` method will be called, passing the 
       ``HttpRequest`` and the new ``User``, to determine the URL to redirect 
       the user to. To override this, see the list of optional arguments for 
       this view (below).
    
    **Required arguments**
    
    ``backend``
        The dotted Python import path to the backend class to use.
    
    **Optional arguments**
    
    ``disallowed_url``
        URL to redirect to if registration is not permitted for the current 
        ``HttpRequest``. Must be a value which can legally be passed to 
        ``django.shortcuts.redirect``. If not supplied, this will be whatever 
        URL corresponds to the named URL pattern ``registration_disallowed``.
    
    ``form_class``
        The form class to use for registration. If not supplied, this will be 
        retrieved from the registration backend.
    
    ``extra_context``
        A dictionary of variables to add to the template context. Any callable 
        object in this dictionary will be called to produce the end result 
        which appears in the context.
    
    ``success_url``
        URL to redirect to after successful registration. Must be a value which 
        can legally be passed to ``django.shortcuts.redirect``. If not 
        supplied, this will be retrieved from the registration backend.
    
    ``template_name``
        A custom template to use. If not supplied, this will default to 
        ``registration/registration_form.html``.
    
    **Context:**
    
    ``form``
        The registration form.
    
    Any extra variables supplied in the ``extra_context`` argument (see above).
    
    **Template:**
    
    registration/registration_form.html or ``template_name`` keyword argument.
    
    """
    backend = get_backend(backend)
    if not backend.registration_allowed(request):
        return redirect(disallowed_url)
    if form_class is None:
        form_class = backend.get_form_class(request)
    
    error = ''
    
    if request.method == 'POST':
        form = form_class(data=request.POST, files=request.FILES)
        if form.is_valid():
            new_user = backend.register(request, **form.cleaned_data)
            if new_user:
                if success_url is None:
                    to, args, kwargs = backend.post_registration_redirect(request, new_user)
                    return redirect(to, *args, **kwargs)
                else:
                    return redirect(success_url)
            else:
                error = _('Registration failed.')
    else:
        form = form_class(initial=request.GET) 
    
    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = value() if callable(value) else value
    
    return render_to_response(template_name,
                              {'form': form, 'error': error},
                              context_instance=context)
    

def validate(request, backend,
             template_name='registration/validation_error.html',
             success_url=None, extra_context=None, **kwargs):
    """
    Validate a user's account.
    
    The actual validation of the account will be delegated to the backend 
    specified by the ``backend`` keyword argument (see below); the backend's 
    ``validate()`` method will be called, passing any keyword arguments 
    captured from the URL, and will be assumed to return a ``User`` if 
    validation was successful, or a value which evaluates to ``False`` in 
    boolean context if not.
    
    Upon successful validation, the backend's ``post_validation_redirect()`` 
    method will be called, passing the ``HttpRequest`` and the validated 
    ``User`` to determine the URL to redirect the user to. To override this, 
    pass the argument ``success_url`` (see below).
    
    On unsuccessful validation, will render the template 
    ``registration/validation_error.html`` to display an error message; to 
    override thise, pass the argument ``template_name`` (see below).
    
    **Arguments**
    
    ``backend``
        The dotted Python import path to the backend class to
        use. Required.
    
    ``extra_context``
        A dictionary of variables to add to the template context. Any
        callable object in this dictionary will be called to produce
        the end result which appears in the context. Optional.
    
    ``success_url``
        The name of a URL pattern to redirect to on successful
        acivation. This is optional; if not specified, this will be
        obtained by calling the backend's
        ``post_validation_redirect()`` method.
    
    ``template_name``
        A custom template to use. This is optional; if not specified,
        this will default to ``registration/validation_error.html``.
    
    ``\*\*kwargs``
        Any keyword arguments captured from the URL, such as an
        validation key, which will be passed to the backend's
        ``validate()`` method.
    
    **Context:**
    
    The context will be populated from the keyword arguments captured
    in the URL, and any extra variables supplied in the
    ``extra_context`` argument (see above).
    
    **Template:**
    
    registration/validation_error.html or ``template_name`` keyword argument.
    
    """
    backend = get_backend(backend)
    account = backend.validate(request, **kwargs)
    
    if account:
        if success_url is None:
            to, args, kwargs = backend.post_validation_redirect(request, account)
            return redirect(to, *args, **kwargs)
        else:
            return redirect(success_url)
    
    if extra_context is None:
        extra_context = {}
    context = RequestContext(request)
    for key, value in extra_context.items():
        context[key] = callable(value) and value() or value
    
    return render_to_response(template_name,
                              kwargs,
                              context_instance=context)
    
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.