Package: django-mail_confirmation
HOW IT WORKSmail_confirmationis a general application for providing object approvation from users via email:you create an object, tellmail_confirmationtogenerate and senda mail confirmation to the user, and theuser confirmsthat object by clicking the url received in theemail.You can provide different templates, sensible defaults are provided, custom views or templates rendered when the user clicks on that confirmation link, and other settings. Stale requests are optionally handled with celery tasks.For now emails are sent as html unless you provide your function to send emails.INSTALLATIONSet the mail confirmation urls:from mail_confirmation.views import MailConfirmation

#Mail url Confirmation
urlpatterns += patterns('',
                          url(r'^confirm/', include('mail_confirmation.urls', namespace='mail_confirmation')),
)put the app ininstalled_appssettings:INSTALLED_APPS += (
    'mail_confirmation',
)and then run syncdbIn themodelthat you want to confirm put a generic relation field:from django.contrib.contenttypes import generic
from mail_confirmation.models import MailConfirmation

confirmed = generic.GenericRelation(MailConfirmation,
                                   content_type_field='toconfirm_type',
                                   object_id_field='toconfirm_id')note also that in the orm you must check forconfirmed__confirmed=True)Youmustalso provide a template inyouapplication/mail_request.htmlthat will be used as email body and a template inyourapplication/mail_confirmation_succeded.htmlthat will display a thank you message for the user, you could override their names, see below.Read below on how to connect to asignalemitted whenever a model is confirmed by the user.SETTINGSsettings.SITE_SCHEMEdefaults to httpsettings.MAIL_CONFIRMATION_STALE_PERIODperiod after deletion of stale requestssettings.DEFAULT_FROM_EMAILif no email is provided as sender use this oneThis app optionally uses thesites frameworkfor retrieving the domain name of your site, andSITE_SCHEMEin your settings to know what scheme (defaults to ‘https’) to use when building urls.USAGENote, you can look uptests/test.pyto see an example of usage, seeMailConfirmationTest.test_confirmationhow uses the relevant object to confirm and how it is made fromtests.modelsCreating your objectsay you have a modelMyModelwith aconfirmedfield of the kind explained above:obj = MyModel()and askmail_confirmationto send a confirmation email to the user.Sending confirmations to the usertogenerate and senda confirmation you put this snippet in your code (see below on how to generate a confirmation and send the email indipendently):from mail_confirmation.utils import generate_and_send

generate_and_send(obj,
                  request_template,
                  success_template, success_url,
                  forusers,
                  mail_function,
                  subject, sender, to, confirmurlname, context)objin an instance of a model that needs a confirmation from the user.requerst_templateoverrides the default template path used for building the request email.success_templateoverrides the default template path used for the success view when the user visits the confirmation url from the emailsuccess_urloptionally you could specify an url to be used as a redirect when the user visits the confirmation url, this is used instead of thesuccess_templateabove.forusersa single or a list of users that can confirm this object, if not provided anyone with the link can confirm this objectmail_functionif you don’t want to use the default send_confirmation function you can specify a function used to send the email, the signature should be the same ofsend_confirmationin utils.py, Note that every additional argument you pass to generate_and_send will be also passed to your custom function.subjectis the optional email subjectsenderis the optional email sendertois the user email, or a list of user email, where the confirmation email is sentconfirmurlnameif you put this app in a different namespace you can configure the url name used byreverseto compose the confirmation url by passingconfirmurlname=’custom_appname:url’tosend_confirmationorgenerate_and_sendcontextis an optional context passed to the email templateThe email is rendered by passing as context an optionalcontextyou provi and various variables used to build the confirmation url:confirmation_urlis the path of that url,SITE_DOMAINandSITE_SCHEMEcontains the site scheme and domain name.Default values:Read this carefully to know where `mail confirmation` looks for picking up various templatesrequest_template:yourapplication/templates/yourapplication/mail_request.htmlyourapplicationis the application the object you are trying to confirm belongs to, for example if I haveobj = appname.MyModel(), then the mail request template will be searched inappname/templates/appname/mail_request.htmlsuccess_template:yourapplication/templates/yourapplication/mail_confirmation_succeded.html,yourapplicationhas the same meaning as abovesubject:“Confirmation mail”success_url: Nonesender:settings.DEFAULT_FROM_EMAILconfirmurlname:mail_confirmation:urlSITE_SCHEME:httpsSITE_DOMAIN: it uses theSiteframework,Site.objects.get_current().domain. or looks in the settings for aSITE_DOMAINattribute.ExampleGiven sensible defaults a generate and send call could be as simple as:::obj = MyModel()
generate_and_send(obj,to=’to@example.com’)NOTEYou could optionallysplit the confirmation generation and sendingby using those two functions,generate_confirmationandsend_confirmation, look atutils.pyto see their signature.Rendering the mail templateThe email template receives your optionalcontextand theSITE_SCHEME,SITE_DOMAINandconfirmation_urlvariables:::Hello, click the link below to confirm your object:
<a href=”{{ SITE_SCHEME }}://{{SITE_DOMAIN}}{{ confirmation_url }}”>url</a>Rendering the success(confirmation) templateThe success template will have theconfirmationobject as context, you can access the object you want to confirm fromconfirmation.toconfirm_object.Getting the confirmed id (listening signals)Whenever a confirmation is made from an user asignalis emitted;
you can connect to that signal and do things™ with this code:from mail_confirmation.signals import confirmed_signal

confirmed_signal.connect(my_callback)or@receiver(confirmed_signal,
          sender=MailConfirmation)
def my_callback(sender, toconfirm_type, object_id, **kwargs):
    if toconfirm_type == MyModel:
        print("do something")where toconfirm_type is the model you passed as instance to the confirmation generation and object_id is the id of your MyModel objectEnforcing permissionsUsually for email confirmations it is enough to rely on the secrecy of the mailed link, some other times we want to be sure that only a given user has access to that link, this is done by associating one or more users to a particular mail confirmation, by providingforusersparameter togenerate_confirmationorgenerate_and_send.This will enforce the permission for the confirmation view, only a certain user if specified can confirm that object, if the user is already logged, a 403 is returned, if the user is anonymous then the login page is showed, with a next parameter of the confirmation url.Clearing stale requestsimport from utils clear_stale() or a celery task that runs every first of the month is provided for you.CELERY_IMPORTS += (
    'mail_confirmation.tasks',
)you also should set  settings.MAIL_CONFIRMATION_STALE_PERIOD to a timedelta in daysit defaults to 30 days, set it to 0 to disable temporarlyTESTS./manage.py test mail_confirmation –settings=mail_confirmation.tests.settingsCHANGELOG1.0:
* possibility to use a custom mail function ingenerate_and_sendinstead of defaultsend_confirmation* corrected the default values ofsend_confirmationfunction
* changed the context in the email fromdomaintoSITE_DOMAINandurltoconfirmation_url* usinguuid4.hexas confirmation ids for confirmation objects, prviously was generated in a slow as hell method.
* passing theconfirmationobject in the rendered success template