a Django waiting list app

pip install pinax-waitinglist==3.0.1


Pinax Waiting List

CircleCi Codecov

Table of Contents

About Pinax

Pinax is an open-source platform built on the Django Web Framework. It is an ecosystem of reusable Django apps, themes, and starter project templates. This collection can be found at

Important Links

Where you can find what you need:



pinax-waitinglist is an app for Django sites for collecting user emails on a waiting list before a site has launched. It also provides basic survey capabilities to gather information from your potential users.

For an out-of-the-box Django project already set up with pinax-waitinglist and Bootstrap templates, see the Pinax waitinglist starter project.

Supported Django and Python Versions

Django / Python 3.6 3.7 3.8
2.2 * * *
3.0 * * *



To install pinax-waitinglist:

$ pip install pinax-waitinglist

Add pinax.waitinglist to your INSTALLED_APPS setting:

    # other apps

Run migrations:

$ python migrate

Add pinax.waitinglist.urls to your project urlpatterns:

urlpatterns = [
    # other urls
    url(r"^waitinglist/", include("pinax.waitinglist.urls", namespace="pinax_waitinglist")),


List Signup

The most basic usage would be to direct users to a page where they can provide their email address to be notified of updates:

Add a TemplateView for a landing page to your

# project/

from django.views.generic import TemplateView

urlpatterns = [
    # other urls
    url(r"^$", TemplateView.as_view(template_name="waitinglist/list_signup.html"), name="home"),

Update your template directories in

# project/
        'DIRS': [
            # other dirs
            os.path.join(BASE_DIR, "templates"),

Add list_signup.html template:

<!-- templates/waitinglist/list_signup.html -->

<div class="site-wrapper-inner">
    <div class="cover-container">
        <div class="inner cover">
            <h1 class="cover-heading">Sign up on our waiting list!</h1>
            <p class="lead">
                Once this site is ready to launch, you will be emailed.
            {% if %}
                <b>{{ }}</b>
            {% endif %}
            {% url "waitinglist_list_signup" as url %}
            <form method="POST" action="{{ url }}" class="form-inline">
                {% csrf_token %}
                <div class="form-group">
                    <label class="sr-only" for="id_email">Email address</label>
                    <input type="email" name="email" class="form-control input-lg" id="id_email" placeholder="">
                <button class="btn btn-default btn-lg">Submit</button>
        <div class="mastfoot">
            <div class="inner">
                <p>{% include "_footer.html" %}</p>

Add a success template success.html:

<!-- templates/waitinglist/success.html -->

<div class="site-wrapper-inner">
    <div class="cover-container">
        <div class="inner cover">
            <h1 class="cover-heading">Thank you!</h1>
            <p class="lead">You are on the list. We will notify you know when this site launches.</p>
                If you have any questions, feel free to email <a href=""><b></b></a>.
        <div class="mastfoot">
            <div class="inner">
                <p>{% include "_footer.html" %}</p>


If you would like to offer a survey after users enter their email:

A survey will need to be created with one or more questions. Surveys and their questions are accessed through the admin interface.

# Add a survey

# Add questions to an existing survey

Add survey.html template:

<!-- templates/waitinglist/survey.html -->

<div class="site-wrapper-inner">
    <div class="cover-container">
        <div class="inner cover">
            <h1 class="cover-heading">Survey</h1>
            <p class="lead">Do you have a moment to answer a few qustions?</p>
                {% csrf_token %}
                {{ form }}
                <button type="submit" class="btn btn-default btn-lg">Submit</button>
        <div class="mastfoot">
            <div class="inner">
                <p>{% include "_footer.html" %}</p>

Email Survey to existing emails

Existing emails can be emailed surveys through a django command, mail_out_survey_links .

A SITE object is passed to both of the following templates, if you haven't enabled the sites framework yet, you will need to do so before proceeding. Additional information on enabling can be found at The “sites” framework.

Add survey_invite_subject.txt template:

    {# templates/waitinglist/survey_invite_subject.txt #}

    Survey from {{ }}

Add survey_invite_body.txt template:

    {# templates/waitinglist/survey_invite_body.txt #}

    Please take a moment to complete a brief survey from
    {{ protocol }}://www.{{ site.domain }}{% url 'waitinglist_survey' instance.code %}

Send survey emails:

$ python mail_out_survey_links

Campaigns and Referrals

Campaigns work by just taking the querystring parameter wlc if present in querystring and records the value to the waitinglist entry. This is useful if you want to track conversions of a particular ad campaign. You can set, for instance,, as the url for the ad. when people click on the ad, and signup, c1 will be added to their entry and is viewable in the admin.

Referrals work the same as campaigns but work automatically. If there a value in request.META["HTTP_REFERER"] when landing on the signup page, the value will get required in the referral field of the waitinglist entry.



Defaults to SECRET_KEY

This is used for generating the hash for pinax.waitinglist.models.SurveyInstance.code.


Defaults to HTTP

Provided as context in certain emails for URL building.


Management Commands

Email links to survey instances for those that never saw a survey. Retrieves the currently active Survey, and filters WaitingListEntry where SurveyInstance is null.

Uses templates waitinglist/survey_invite_subject.txt & waitinglist/survey_invite_body.txt for emails.


Default templates are provided by the pinax-templates app in the waitinglist section of that project.

Reference pinax-templates installation instructions to include these templates in your project.

View live pinax-templates examples and source at Pinax Templates!

Customizing Templates

Override the default pinax-templates templates by copying them into your project subdirectory pinax/waitinglist/ on the template path and modifying as needed.

For example if your project doesn't use Bootstrap, copy the desired templates then remove Bootstrap and Font Awesome class names from your copies. Remove class references like class="btn btn-success" and class="icon icon-pencil" as well as bootstrap from the {% load i18n bootstrap %} statement. Since bootstrap template tags and filters are no longer loaded, you'll also need to update {{ form|bootstrap }} to {{ form }} since the "bootstrap" filter is no longer available.


Rendered by ajax_list_signup view when form is not valid and gets passed form (WaitingListEntryForm) in context.


Rendered by ajax_list_signup view when form is valid.

User-Provided Templates

Create these templates in a pinax/waitinglist/ subfolder in your template search path.


Rendered by list_signup view and gets passed form (WaitingListEntryForm) in context.


Rendered by django.views.generic.TemplateView.


Rendered by survey view when request method is GET and gets passed form (SurveyForm) in context.


Rendered by mail_out_survey_links command and gets passed instance (SurveyInstance instance), site (Site instance) and protocol (DEFAULT_HTTP_PROTOCOL setting).


Rendered by mail_out_survey_links command and gets passed instance (SurveyInstance instance), site (Site instance) and protocol (DEFAULT_HTTP_PROTOCOL setting).


Rendered by django.views.generic.TemplateView after successfully adding user to waiting list.



Triggedered when a user completes a survey through SurveyForm which is used with survey view.

Provides argument form (SurveyForm instance).


Triggered when a user signs up through ajax_list_signup or list_signup views.

Provides argument entry (WaitingListEntry instance).

Change Log


  • Add an admin action to export the waiting list as csv


  • Drop Django 1.11, 2.0, and 2.1, and Python 2,7, 3.4, and 3.5 support
  • Add Django 2.2 and 3.0, and Python 3.6, 3.7, and 3.8 support
  • Update packaging configs
  • Direct users to community resources


  • Fix render_to_string context_instances kwarg
  • Fix package_data reference for included templates
  • Add pinax-templates support


  • Update CI configuration
  • Remove docs build support
  • Improve documentation markup




  • Add Django 2.0 compatibility testing
  • Drop Django 1.8, 1.9, 1.10 and Python 3.3 support
  • Convert CI and coverage to CircleCi and CodeCov
  • Add PyPi-compatible long description
  • Move documentation to


  • fixed problem with survey choices in Python 3


  • added campaign tracking
  • added referral tracking


  • added a simple management command to export waitinglist entries


  • fixed paths in mail out email management command


  • don't show empty label in radio choice survey questions


Contributing information can be found in the Pinax community health file repo.

Code of Conduct

In order to foster a kind, inclusive, and harassment-free community, the Pinax Project has a Code of Conduct. We ask you to treat everyone as a smart human programmer that shares an interest in Python, Django, and Pinax with you.

Connect with Pinax

For updates and news regarding the Pinax Project, please follow us on Twitter @pinaxproject and check out our Pinax Project blog.


Copyright (c) 2012-present James Tauber and contributors under the MIT license.