From 30101453a75aaa635e3458d509dec164a6a68ac1 Mon Sep 17 00:00:00 2001 From: Matthew Lemon Date: Thu, 5 Dec 2024 17:42:08 +0000 Subject: Add unique constraint to EmailVerification email field This update enhances the EmailVerification model by ensuring the email field is unique, preventing duplicate records. A new form, EmailVerificationForm, was also introduced to handle email cleaning and validation, which enhances user input handling. Additionally, existing views and templates have been updated to integrate this form, improving the user experience and error feedback. --- alphabetlearning/payments/forms.py | 14 + .../0013_alter_emailverification_email.py | 18 ++ alphabetlearning/payments/models.py | 3 +- alphabetlearning/payments/views.py | 147 ++++++----- alphabetlearning/templates/pages/home.html | 282 +++++++++++---------- 5 files changed, 267 insertions(+), 197 deletions(-) create mode 100644 alphabetlearning/payments/forms.py create mode 100644 alphabetlearning/payments/migrations/0013_alter_emailverification_email.py (limited to 'alphabetlearning') diff --git a/alphabetlearning/payments/forms.py b/alphabetlearning/payments/forms.py new file mode 100644 index 0000000..f69397f --- /dev/null +++ b/alphabetlearning/payments/forms.py @@ -0,0 +1,14 @@ +from django import forms +from .models import EmailVerification + + +class EmailVerificationForm(forms.ModelForm): + class Meta: + model = EmailVerification + fields = ['email'] + + def clean_email(self): + email = self.cleaned_data.get('email') + if EmailVerification.objects.filter(email=email).exists(): + raise forms.ValidationError("This email address is already in use.") + return email \ No newline at end of file diff --git a/alphabetlearning/payments/migrations/0013_alter_emailverification_email.py b/alphabetlearning/payments/migrations/0013_alter_emailverification_email.py new file mode 100644 index 0000000..5d537bb --- /dev/null +++ b/alphabetlearning/payments/migrations/0013_alter_emailverification_email.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.4 on 2024-12-05 16:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('payments', '0012_rename_pendingemailverification_emailverification'), + ] + + operations = [ + migrations.AlterField( + model_name='emailverification', + name='email', + field=models.EmailField(max_length=254, unique=True), + ), + ] diff --git a/alphabetlearning/payments/models.py b/alphabetlearning/payments/models.py index 9ea9de2..3a3ba10 100644 --- a/alphabetlearning/payments/models.py +++ b/alphabetlearning/payments/models.py @@ -10,7 +10,7 @@ from alphabetlearning.resources.models import Resource class EmailVerification(models.Model): - email = models.EmailField() + email = models.EmailField(unique=True) verification_token = models.UUIDField(default=uuid.uuid4, editable=False) created_at = models.DateTimeField(auto_now_add=True) is_verified = models.BooleanField(default=False) @@ -23,7 +23,6 @@ class EmailVerification(models.Model): def __str__(self): return f"Email verification for {self.email}" - class EmailSignup(models.Model): email = models.EmailField(unique=True) date_added = models.DateTimeField(auto_now_add=True) diff --git a/alphabetlearning/payments/views.py b/alphabetlearning/payments/views.py index 4b6f79f..dda7900 100644 --- a/alphabetlearning/payments/views.py +++ b/alphabetlearning/payments/views.py @@ -18,7 +18,7 @@ from alphabetlearning.payments.models import EmailSignup from alphabetlearning.payments.models import EmailVerification from alphabetlearning.resources.models import Resource from alphabetlearning.users.models import User - +from .forms import EmailVerificationForm from .models import CartItem from .models import Price from .models import ShoppingCart @@ -56,70 +56,101 @@ class SuccessEmailSignupView(TemplateView): def email_signup_verification(request): if request.method == "POST": - email = request.POST.get("email") - - # Create pending verification - pending_verification = EmailVerification.objects.create( - email=email, - ) - - # Generate verification URL - verification_url = request.build_absolute_uri( - reverse('payments:verify_email', args=[str(pending_verification.verification_token)]) - ) - - # Send verification email - subject = 'Alphabet Learning - Email Verification' - html_message = f''' - - - Alphabet Learning Logo -

Hi!

-

You recently requested to sign up to the Alphabet Learning contact list.

-

Please click the following link to verify your email address within 24 hours:

-

{verification_url}

-

If you didn't request this, please ignore this email.

-

Best regards,

-

The Alphabet Learning Team

- - + form = EmailVerificationForm(request.POST) + if form.is_valid(): + # Create pending verification + pending_verification = EmailVerification.objects.create( + email=form.cleaned_data.get("email"), + ) + # Generate verification URL + verification_url:str = request.build_absolute_uri( + reverse('payments:verify_email', args=[str(pending_verification.verification_token)]) + ) + email = process_verification_emails(verification_url, form.cleaned_data.get("email"), pending_verification, request) + return render(request, 'payments/verification_sent.html', { + 'email': email + }) + else: + email = process_verification_emails(request.POST.get("email"), warn=True) + return render(request, 'payments/verification_sent.html', { + 'email': email + }) + else: + form = EmailVerificationForm() + return render(request, "pages/home.html", {"form": form}) # Adjust as necessary + + +def process_verification_emails(email: str, verification_url: str=False, email_verification_obj: EmailVerification=False, warn=False): + + if warn is False: + html_warning_message = f''' +

Please click the following link to verify your email address within 24 hours:

+

{verification_url}

+

If you didn't request this, please ignore this email.

''' - message = f''' - Hi!, - - You recently requested to sign up to the Alphabet Learning contact list. - + warning_message = f''' Please click the following link to verify your email address within 24 hours: {verification_url} If you didn't request this, please ignore this email. - - Best regards, - The Alphabet Learning Team ''' - send_mail( - subject, - message, - settings.DEFAULT_FROM_EMAIL, - [email], - fail_silently=False, - html_message=html_message - ) - admin_message = f''' - Joanna/Matthew, - - {email} has just signed up to the Alphabet Learning contact list. They are awaiting verification. - - I will email again if they follow through with the verification. - - Best regards, - The Alphabet Learning Server + admin_warn = "They are not already subscribed." + else: + html_warning_message = f''' +

You are already subscribed to our list - no further action is required.

''' + warning_message = ''' + You are already subscribed to our list - no further action is required. + ''' + admin_warn = "They have already subscribed so have been told of this fact in their verification email. No further action required." + + # Send verification email + subject = 'Alphabet Learning - Email Verification' + html_message = f''' + + + Alphabet Learning Logo +

Hi!

+

You recently requested to sign up to the Alphabet Learning contact list.

+ {html_warning_message} +

Best regards,

+

The Alphabet Learning Team

+ + + ''' + message = f''' + Hi!, + + You recently requested to sign up to the Alphabet Learning contact list. + + {warning_message} + + Best regards, + The Alphabet Learning Team + ''' + send_mail( + subject, + message, + settings.DEFAULT_FROM_EMAIL, + [email], + fail_silently=False, + html_message=html_message + ) + admin_message = f''' + Joanna/Matthew, + + {email} has just signed up to the Alphabet Learning contact list. They are awaiting verification. + + {admin_warn} + + I will email again if they follow through with the verification. + + Best regards, + The Alphabet Learning Server + ''' + mail_admins(subject, admin_message, fail_silently=False) + return email + - mail_admins(subject, admin_message, fail_silently=False) - return render(request, 'payments/verification_sent.html', { - 'email': email - }) - return render(request, "pages/home.html") # Adjust as necessary def verify_email(request, token): try: pending = EmailVerification.objects.get( diff --git a/alphabetlearning/templates/pages/home.html b/alphabetlearning/templates/pages/home.html index bda011c..e0827c1 100644 --- a/alphabetlearning/templates/pages/home.html +++ b/alphabetlearning/templates/pages/home.html @@ -1,18 +1,18 @@ {% extends "base.html" %} {% load static %} {% block content %} -
-
-
-

Alphabet Learning

-

- High quality educational resources focused on simple concepts - and the first steps in learning. -

+
+
+
+

Alphabet Learning

+

+ High quality educational resources focused on simple concepts + and the first steps in learning. +

+
-
-
+ /> -
-
-

Sign up

-
-

- To be informed of the site launch and receive FREE resource - credits, join our new customer mailing list... -

-
-
- {% csrf_token %} -
-
- -
- -
-

- + Submit + +

+

+ By joining our list, you agree to our - Privacy and Legal Notice. + >. +

+ +
+
+

Bonus offer!

+

+ As a thank-you, the first fifty customers who join our mailing + list will receive a 50% discount once the site is live.

- -
-
-

Bonus offer!

-

- As a thank-you, the first fifty customers who join our mailing - list will receive a 50% discount once the site is live. -

+
-
-
+ /> -
-
- Funnel 1 -
-
- Funnel 2 -
-
- Funnel 3 +
+
+ Funnel 1 +
+
+ Funnel 2 +
+
+ Funnel 3 +
-
-
-
-
-

- Learning from A to Z +
+
+
+

+ Learning from A to Z +

+

+ Focused on early concepts, these resources are designed to + be accessible to all learners. +

+
+
+
+

+ No commitment required

-

- Focused on early concepts, these resources are designed to - be accessible to all learners. +

+ Resources will be available to purchase individually without a + subscription.

-
-

- No commitment required -

-

- Resources will be available to purchase individually without a - subscription. -

-
-

-
-
- Funnel 1 -
-
- Funnel 2 -
-
- Funnel 3 +
+
+ Funnel 1 +
+
+ Funnel 2 +
+
+ Funnel 3 +
+

+ Alphabet Learning is currently in active
development and will be + launched in Spring 2025. +

-

- Alphabet Learning is currently in active
development and will be - launched in Spring 2025. -

-
{% endblock content %} -- cgit v1.2.3