Skip to main content

Wagtail Honeypot

Alt text

Add optional form spam protection to your Wagtail forms

It should help to reduce form spam by tricking bots into submitting data in fields that should remain empty.

How it works

When the Wagtail Form is submitted and the honeypot protection is enabled, the honeypot fields & values are available in the POST data.

It provides validation for a hidden text field that should remain empty and checks a time interval between the form being displayed and submitted.

If the form is submitted with content in the hidden field or before the interval expires the submission is ignored.

  • No email is sent
  • No submission is stored

Installation and setup

Add the package to your python environment.

pip install wagtail-honeypot

Add the package to your settings

INSTALLED_APPS = [
    ...
    "wagtail_honeypot",
    ...
]

The HoneypotFormMixin & HoneypotFormSubmissionMixin

They will add a honeypot enable/disable field to your form page model and custom form submission method.

If you follow the official Wagtail docs for the Form Builder your form should look something like this...

from wagtail_honeypot.models import (
    HoneypotFormMixin, HoneypotFormSubmissionMixin
)

class FormField(AbstractFormField):
    page = ParentalKey("FormPage", related_name="form_fields")

class FormPage(HoneypotFormMixin, HoneypotFormSubmissionMixin):
    intro = RichTextField(blank=True)
    thank_you_text = RichTextField(blank=True)

    content_panels = AbstractEmailForm.content_panels + [
        FieldPanel("intro", classname="full"),
        InlinePanel("form_fields", label="Form fields"),
        FieldPanel("thank_you_text", classname="full"),
        MultiFieldPanel(
            [
                FieldRowPanel(
                    [
                        FieldPanel("from_address", classname="col6"),
                        FieldPanel("to_address", classname="col6"),
                    ]
                ),
                FieldPanel("subject"),
            ],
            "Email",
        ),
    ]

    honeypot_panels = [
        MultiFieldPanel(
            [FieldPanel("honeypot")],
            heading="Reduce Form Spam",
        )
    ]

    edit_handler = TabbedInterface(
        [
            ObjectList(content_panels, heading="Content"),
            ObjectList(honeypot_panels, heading="Honeypot"),
            ObjectList(Page.promote_panels, heading="Promote"),
            ObjectList(Page.settings_panels, heading="Settings", classname="settings"),
        ]
    )

If you prefer you could add the honeypot field to the content_panels rather than a new Tab

# replace
edit_handler = TabbedInterface(
        [
            ObjectList(content_panels, heading="Content"),
            ObjectList(honeypot_panels, heading="Honeypot"),
            ObjectList(Page.promote_panels, heading="Promote"),
            ObjectList(Page.settings_panels, heading="Settings", classname="settings"),
        ]
    )

# with
content_panels = content_panels + honeypot_panels

Run python manage.py makemigrations and python manage.py migrate here

Honeypot Template Tag

Add the following template tag loader to your form page.

{% load honeypot_tags %}

Add the Honeypot fields template tag anywhere inside the form

<form>
...
{% honeypot_fields page.honeypot %}
...
</form>

In your Wagtail site you should now be able to add a new form page, enable the honeypot field.

Test that the honey pot field works

  1. View the newly created form page.
  2. The honeypot field is visible and could be submitted with any value.
  3. Test it out by submitting the form with the honeypot field set to any value. It won't save the form submission or send an email if you have enabled that in your form page.

Hide the Honeypot field

The honeypot field should be invisible to when viewed in a browser.

Use CSS & JS to hide the honeypot field

The package has some basic css and javascript you can use to hide the field.

Example: add the following to your form template.

<!-- recommended:
to add both but you can use one or the other -->

{% block extra_css %}
<link rel="stylesheet" href="{% static 'css/honeypot.css' %}">
{% endblock extra_css %}

<!-- alternative:
but without the css above loaded first
the field could be seen for a flash while the page loads -->

{% block extra_js %}
<script src="{% static 'js/honeypot.js' %}"></script>
{% endblock extra_js %}

The field should be visibly hidden and not be available to receive any value from a site visitor.

When rendered, the fields will have the HTML attributes tabindex="-1" autocomplete="off" aria-hidden="true" to keep them out of normal keyboard navigation, disable browser autocomplete, and hide them from assistive technology.

Developer Documentation

Developer Docs for detailed help.

Versions

Wagtail honey pot can be used in environments:

  • Python 3.10+
  • Django 4.2+
  • Wagtail 6.3+

Contributions

Contributions or ideas to improve this package are welcome.

Release files for wagtail-honeypot 1.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wagtail-honeypot 1.3.1
File Size Uploaded
wagtail_honeypot-1.3.1.tar.gz 14.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wagtail-honeypot 1.3.1
File Interpreter ABI Platform
wagtail_honeypot-1.3.1-py3-none-any.whl Python 3 none any Details

Total release size:22.7 kB

Release files / wagtail_honeypot-1.3.1.tar.gz

Download URL wagtail_honeypot-1.3.1.tar.gz
Size 14.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e09cbb99ef6e18b98a3c36b06d9c2b7bd357477af4470404146af55d567528ff
BLAKE2b-256 checksum
How to use checksums
23c7d2a6130617ca2f1b0279ef80b93e034cc1b426b0d7b52ac1a3d76996bf5a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.

Transparency log

Release files / wagtail_honeypot-1.3.1-py3-none-any.whl

Download URL wagtail_honeypot-1.3.1-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
793f7bf91cdc8cf9b2516c4e6a274f939bfa94ef977fe031cabeef6c5e47cd91
BLAKE2b-256 checksum
How to use checksums
3b1770dc2a8f118046a9d12f67ea8061de2fe78e4a9d9bfdb9f42345d9cc42a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.3.1 This release

2 release files

1.3.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page