A waitlist, sometimes called a "pre-launch list" or "signup list" is a mechanism for people to express their interest in a product that is not yet available or in development. A waitlist is created for people to essentially join a queue, hoping to be among the first to access that product when it launches. People who have signed up on a waitlist can also get occasional emails about the progress of the product in development and to hype them up too.
In this guide, you will learn how to create a simple waitlist signup form with Django, store emails in a database, and send an automatic reply email using an SMTP service. Let's get started!
SMTP stands for Simple Mail Transfer Protocol. It is a protocol used for sending emails between servers.
Prerequisites
Before we begin, make sure you have Python installed on your computer. If not, you can download and install it from python.org. Additionally, you'll need a code editor, such as Visual Studio Code or PyCharm.
Before you continue, I expect you to have:
a basic knowledge of Python and Django
a standard knowledge of HTML and CSS too (to create a UI for the form)
a basic knowledge of how to use the terminal
Create a Django Project and App
Open your terminal and run the following commands:
# Change your directory to desktop
cd desktop
# Create a virtual environment
python3 -m venv venv #(mac os)
Python -m venv venv #(Windows)
# Activate the virtual environment
source venv/bin/activate #(mac os)
venv\Scripts\activate.bat #(windows)
# Install Django
pip install django
# Create a new Django project
django-admin startproject waitlist_project
# Move into the project directory
cd waitlist_project
# Create a new Django app
python manage.py startapp waitlist
Run your server to ensure your app is working well:
python manage.py runserver
Now you've successfully set up your Django project. Open Vscode or any text editor of your choice and let's write some code!
Add your Django app to settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'waitlist', #Add this line
]
Define the Model
Open the waitlist/
models.py
file in your code editor and define a simple model to represent waitlist entries:
# waitlist/models.py
from django.db import models
class WaitlistEntry(models.Model):
email = models.EmailField(unique=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.email
Create a Form
In the waitlist/
folder create a forms.py
file, and a form to handle email input:
# waitlist/forms.py
from django import forms
from .models import WaitlistEntry
class WaitlistForm(forms.ModelForm):
class Meta:
model = WaitlistEntry
fields = ['email']
Styling and Templates
Create a static folder and a CSS file in this format: (static/waitlist/styles.css
) for styling and a template (templates/waitlist/signup.html
) in the waitlist folder for your signup page. Make sure you create the necessary folders and files in these specified arrangements.
<!-- waitlist/templates/waitlist/signup.html -->
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Waitlist Signup</title>
<link rel="stylesheet" href="{% static 'waitlist/styles.css' %}">
</head>
<body>
<h2>Join Our Waitlist</h2>
<form method="post" action="{% url 'waitlist_signup' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Join Now</button>
</form>
</body>
</html>
Here is the CSS style:
/* static/waitlist/styles.css */
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
margin: 20px;
}
h2 {
color: #333;
}
form {
max-width: 400px;
margin: 0 auto;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
input[type="email"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
box-sizing: border-box;
}
button {
background-color: #4caf50;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
Load static files
In your waitlist_project/
settings.py
file, make sure you have the following configurations:
# waitlist_project/settings.py
# Static files (CSS, JavaScript, images)
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'waitlist/static')]
This configuration tells Django to look for static files in the static
directory inside your waitlist
app.
Implement a View
In the waitlist/
views.py
file, create a view to handle the form submission, and save emails to the database:
# waitlist/views.py
from django.shortcuts import render, redirect
from .forms import WaitlistForm
def waitlist_signup(request):
if request.method == 'POST':
form = WaitlistForm(request.POST)
if form.is_valid():
form.save()
return redirect('success_page') # Redirect to a success page
else:
form = WaitlistForm()
return render(request, 'waitlist/signup.html', {'form': form})
Configure URLs
Update the waitlist/
urls.py
and waitlist_project/
urls.py
files to include the new view:
-
# waitlist/urls.py from django.urls import path from .views import waitlist_signup urlpatterns = [ path('signup/', waitlist_signup, name='waitlist_signup'), ]
-
# waitlist_project/urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('waitlist/', include('waitlist.urls')), ]
Create a Success Page Template:
Create a new HTML file for your success page, for example, success.html
:
<!-- waitlist/templates/waitlist/success.html -->
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Waitlist Success</title>
<link rel="stylesheet" href="{% static 'waitlist/styles.css' %}">
<style>
body {
font-family: Arial, sans-serif;
background-color: #f8f8f8;
text-align: center;
padding: 50px;
}
h2 {
color: #4caf50;
}
p {
color: #333;
}
</style>
</head>
<body>
<h2>Thank You for Joining Our Waitlist!</h2>
<p>We will keep you updated. Stay tuned!</p>
</body>
</html>
Update the views.py
:
In your waitlist/
views.py
, create a success_page
view to redirect to the success page upon successful form submission:
# waitlist/views.py
from django.shortcuts import render, redirect
from .forms import WaitlistForm
def waitlist_signup(request):
if request.method == 'POST':
form = WaitlistForm(request.POST)
if form.is_valid():
form.save()
return redirect('success_page') # Redirect to the success page
else:
form = WaitlistForm()
return render(request, 'waitlist/signup.html', {'form': form})
# Add this line
def success_page(request):
return render(request, 'waitlist/success.html')
Update urls.py
:
In your waitlist/
urls.py
, include a new URL pattern for the success page:
# waitlist/urls.py
from django.urls import path
from .views import waitlist_signup, success_page
urlpatterns = [
path('signup/', waitlist_signup, name='waitlist_signup'),
path('success/', success_page, name='success_page'), # Add this line
]
Update settings.py
for Success Page URL:
In your waitlist_project/
settings.py
, make sure the SUCCESS_URL
is defined:
# waitlist_project/settings.py
# Define the success URL for the WaitlistForm
SUCCESS_URL = '/waitlist/success/'
Now, when a user successfully submits the form, they will be redirected to the success.html
page. Adjust the URLs and file paths based on your specific project structure if necessary.
Configure SMTP for Auto-Reply
There are so many email service providers you can use but I would be using Brevo in this tutorial because it has a free plan and allows up to 300 emails per day.
Sign Up on Brevo:
Visit the Brevo website and sign up for a free account.
Generate SMTP details:
After signing in to your Brevo account, click on the profile dropdown by the right top corner of the dashboard and navigate to the "SMTP&API" section. Obtain the default SMTP server address, port, and other details. You can also generate a new one.
Update Django Settings
Now, let's update your Django project settings to use Brevo as the SMTP service.
-
Update the
waitlist_project/
settings.py
file with the Brevo SMTP details:# waitlist_project/settings.py EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp-relay.brevo.com' # Replace with your Brevo SMTP server EMAIL_PORT = 587 # Use Brevo's recommended port EMAIL_USE_TLS = True EMAIL_HOST_USER = 'login' # Use the defualt email as 'login' EMAIL_HOST_PASSWORD = 'your-brevo-key-value' # Replace with your Brevo SMTP key value
You can use Port
2525
if you get a 'connected host' error Update Model with Signal: In the
waitlist/
models.py
file, add a signal to send an auto-reply when a new entry is created:# waitlist/models.py # ... (existing code) from django.db.models.signals import post_save from django.dispatch import receiver from django.core.mail import send_mail @receiver(post_save, sender=WaitlistEntry) def send_auto_reply(sender, instance, created, **kwargs): if created: subject = 'Thank you for joining our waitlist!' message = 'Thank you for joining our waitlist. We will keep you updated!' from_email = 'your@example.com' # Replace with your email address recipient_list = [instance.email] send_mail(subject, message, from_email, recipient_list)
Replace the from_email
value with your SMTP registered email on Brevo or any platform you used.
Run Migrations
Run migrations to apply changes:
python manage.py makemigrations
python manage.py migrate
Start the development server:
python manage.py runserver
Visit 127.0.0.1:8000/waitlist/signup in your browser, submit an email, and check your inbox for the auto-reply.
Error Handling
Note: You might get this error even after configuring your project settings correctly:
SMTPDataError at /waitlist/signup/
(502, b'5.7.0 Your SMTP account is not yet activated. Please contact us at contact@sendinblue.com to request activation.')
This is a server error and it did not occur from your side. Try to send an email to that contact and wait for them to activate your SMTP account. You can use any other SMTP service provider that works better than this.
Hosting
You can host your Django project on various platforms for free. see here
Conclusion
In this comprehensive guide, you've learned how to create a robust waitlist application with Django, incorporating essential features like a signup form, email storage, and an auto-reply mechanism using an SMTP service.
As you embark on your journey to building and customizing waitlists, remember that this guide serves as a foundational resource. Feel free to explore additional features, integrate more advanced functionalities, and adapt the project to suit your specific needs.