Python Django 2 Email Verification on User SignUp

I'm working on a project using Python(3.6) and Django(2.0) in which I need to verify the user's email on registration.

Here's what I have tried:

App to users named as users

forms.py

class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
    last_name = forms.CharField(max_length=30, required=False, help_text='Optional.')
    email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')

    def save(self, commit=True):
        user = super(SignUpForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.password = self.cleaned_data['password1']
        if commit:
            user.save()
        return user

urls.py:

urlpatterns = [
    path('signup/', views.SignUpView.as_view(), name='signup'),
    path('login/', views.LoginView.as_view(), name='login'),
    path('logout/', views.LogoutView.as_view(), name='logout'),
    url(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        views.activate, name='activate'),

views.py:

class SignUpView(generic.CreateView):
form_class = forms.SignUpForm
template_name = 'users/signup.html'
success_url = reverse_lazy('users:login')
form_valid_message = 'User has been created successfully!'
form_invalid_message = 'Something wrong'

def post(self, request, *args, **kwargs):
    if request.method == 'POST':
        print('Get post signup')
        form = forms.SignUpForm(request.POST)
        print(request.POST)
        if form.is_valid():
            print('Form is valid')
            fd = form.cleaned_data
            username = fd['username']
            email = fd['email']
            password1 = fd['password1']
            password2 = fd['password2']
            password = None
            if password1 == password2:
                password = password1

            if not (User.objects.filter(username=username).exists() or User.objects.filter(email=email).exists()):
                userObj = User.objects.create_user(username, email, password)
                userObj.first_name = fd['first_name']
                userObj.last_name = fd['last_name']
                userObj.is_active = False
                userObj.save()
                print(userObj)
                current_site = get_current_site(request)
                mail_subject = 'Activate your blog account.'
                message = render_to_string('acc_active_email.html', {
                    'user': User,
                    'domain': current_site.domain,
                    'uid': urlsafe_base64_encode(force_bytes(userObj.pk)).decode(),
                    'token': account_activation_token.make_token(userObj),
                })
                to_email = form.cleaned_data.get('email')
                email = EmailMessage(
                    mail_subject, message, to=[to_email]
                )
                email.send()
                # user = authenticate(username=username, password=password)
                # login(request, user)

                return HttpResponseRedirect('/users/login')
            else:
                return "This Email Already exists, Use another email address please!"

    else:
        form = forms.SignUpForm()

    return render(request, 'users/signup.html', {'form': form})


def activate(request, uidb64, token):
    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()
        login(request, user)
        # return redirect('home')
        return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
    else:
        return HttpResponse('Activation link is invalid!')

And I have craeted a template in my templates directory as:

{% autoescape off %}
Hi {{ user.username }},
Please click on the link to confirm your registration,
http://{{ domain }}{% url 'users:activate' uidb64=uid token=token %}
{% endautoescape %}

When I make a signup request, it returns an error like below:

Form is valid Internal Server Error: /users/signup/ Traceback (most recent call last): File "/Users/abdul/PycharmProjects/Dmitry/DVirEnv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner response = get_response(request) File "/Users/abdul/PycharmProjects/Dmitry/DVirEnv/lib/python3.6/site-packages/django/utils/deprecation.py", line 93, in call response = self.process_response(request, response) File "/Users/abdul/PycharmProjects/Dmitry/DVirEnv/lib/python3.6/site-packages/django/middleware/clickjacking.py", line 26, in process_response if response.get('X-Frame-Options') is not None: AttributeError: 'str' object has no attribute 'get' [08/Nov/2018 06:20:44] "POST /users/signup/ HTTP/1.1" 500 56497

1 answer

  • answered 2018-11-08 06:38 Abdul Niyas P M

    This is because you are returning plain string object instead of valid HTTPResponse.

    return "This Email Already exists, Use another email address please!"
    

    Note: You are trying to signup with existing email address.