I figured out a solution , but for the second requirement user has to input the password at the time of account creation . The main goal was to verify the user supplied email.
Models
class Yourmodel(models.Model):
first_name = models.CharField(max_length=200)
second_name = models.CharField(max_length=200)
email = models.EmailField(max_length=100)
Tokens
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six
class TokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
six.text_type(user.pk) + six.text_type(timestamp) +
six.text_type(user.is_active)
)
account_activation_token = TokenGenerator()
Views
from django.contrib.auth import get_user_model
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.contrib.sites.shortcuts import get_current_site
from .tokens import account_activation_token
from django.core.mail import send_mail
from django.utils.encoding import force_bytes
from django.template.loader import render_to_string
def signup(request):
User = get_user_model()
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
email = form.cleaned_data.get('email')
if Yourmodel.objects.filter(email__iexact=email).count() == 1:
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
mail_subject = 'Activate your account.'
message = render_to_string('email_template.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('email')
send_mail(mail_subject, message, 'youremail', [to_email])
return HttpResponse('Please confirm your email address to complete the registration')
else:
form = SignupForm()
return render(request, 'regform.html', {'form': form})
def activate(request, uidb64, token):
User = get_user_model()
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.save()
return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
else:
return HttpResponse('Activation link is invalid!')
Forms
from django.contrib.auth.forms import UserCreationForm
class SignupForm(UserCreationForm):
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
Email Template
{% autoescape off %}
Hi ,
Please click on the link to confirm your registration,
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
{% endautoescape %}
regform.html
{% csrf_token %}
{% for field in form %}
<label >{{ field.label_tag }}</label>
{{ field }}
{% endfor %}
If you don't want to compare with email address in your model you can
skip, this will send the email to the email address which was supplied
at the time registration without further validation.
email = form.cleaned_data.get('email')
if Yourmodel.objects.filter(email__iexact=email).count() == 1:
default_token_generator
where they use pk, pasword, login_timestamp, timestamp, and email. Does altering it make it any less secure? – Lubricious