A Django app for integrating Cloudflare Turnstile CAPTCHA protection with support for HTMX.
Project description
Django Turnstile HTMX
A Django app for integrating Cloudflare Turnstile CAPTCHA protection with support for HTMX.
Features
- Easy integration with Django views and templates
- Support for both regular forms and HTMX requests
- Server-side validation via decorator
- Simple template tag for adding Turnstile to forms
Installation
-
Install the package from PyPI:
pip install django-turnstile-htmx
-
Add the app to
INSTALLED_APPSin yoursettings.py:INSTALLED_APPS = [ # ... 'turnstile_htmx.apps.TurnstileHtmxConfig', # ... ]
-
Configure Cloudflare Turnstile keys:
CLOUDFLARE_TURNSTILE_SITE_KEY = 'your-site-key-here' CLOUDFLARE_TURNSTILE_SECRET_KEY = 'your-secret-key-here'
Usage
-
Add script to base template:
{% load turnstile_tags %} <head> {% turnstile_script %} </head> -
Add Turnstile field to forms:
{% load turnstile_tags %} <!-- Regular form --> <form method="post"> {% csrf_token %} {{ form.as_p }} {% turnstile_field %} <button type="submit">Submit</button> </form> <!-- HTMX form --> <form hx-post="{% url 'your-view' %}" hx-target="#result"> {% csrf_token %} <input type="email" name="email" required> {% turnstile_field %} <button type="submit">Subscribe</button> </form> -
Protect views with decorator:
from turnstile_htmx.decorators import turnstile_protected @turnstile_protected def contact_form_view(request): # Process form - validation already happened! return render(request, 'contact.html')
API Reference
Template Tags
-
{% turnstile_field %}- Renders the Turnstile widget- Parameters:
container_id(optional),site_key(optional)
- Parameters:
-
{% turnstile_script %}- Renders the Turnstile script tag
Decorators
@turnstile_protected- Validates Turnstile token on POST requests- Parameters:
error_template(optional)
- Parameters:
Examples
Contact Form
<!-- Template -->
{% extends 'base.html' %}
{% load turnstile_tags %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{% turnstile_field %}
<button type="submit">Send</button>
</form>
{% endblock %}
# View
from turnstile_htmx.decorators import turnstile_protected
@turnstile_protected
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
form.save()
return redirect('success')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
Customization
# Custom error template
@turnstile_protected(error_template='<div class="alert">Verification failed!</div>')
def my_view(request):
# ...
# Custom container ID
{% turnstile_field container_id="my-turnstile" %}
Troubleshooting
- Widget not appearing: Check that
{% turnstile_script %}is included and site key is correct - Validation failing: Verify secret key and check browser console for errors
- HTMX issues: Ensure HTMX is loaded before Turnstile script
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_turnstile_htmx-0.1.0.tar.gz.
File metadata
- Download URL: django_turnstile_htmx-0.1.0.tar.gz
- Upload date:
- Size: 7.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da90457c27bdc9a55a8cc26e7720dcf0c7c506a21a85832d3e848daa83305171
|
|
| MD5 |
869f87457e1383a75b382740a8844e3b
|
|
| BLAKE2b-256 |
fa2986a93637fcf67be6325ca7e3dc1c1e32e0759d8770fbf681707504044499
|
Provenance
The following attestation bundles were made for django_turnstile_htmx-0.1.0.tar.gz:
Publisher:
publish.yml on MiKatre/django-turnstile-htmx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_turnstile_htmx-0.1.0.tar.gz -
Subject digest:
da90457c27bdc9a55a8cc26e7720dcf0c7c506a21a85832d3e848daa83305171 - Sigstore transparency entry: 538478471
- Sigstore integration time:
-
Permalink:
MiKatre/django-turnstile-htmx@7b1ad8c431e1c3e24d589a4f95d80d1dc14465f4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/MiKatre
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7b1ad8c431e1c3e24d589a4f95d80d1dc14465f4 -
Trigger Event:
release
-
Statement type:
File details
Details for the file django_turnstile_htmx-0.1.0-py3-none-any.whl.
File metadata
- Download URL: django_turnstile_htmx-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88eaa3e40e5367f0b070054aa16ebc31c7c122bcf4f07883978719327a88763a
|
|
| MD5 |
ffd3b189b8cc931845fb068aa53447be
|
|
| BLAKE2b-256 |
748cacec277da70801dea075475df5f94e36d3ffdccde28417f0e761079355c1
|
Provenance
The following attestation bundles were made for django_turnstile_htmx-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on MiKatre/django-turnstile-htmx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_turnstile_htmx-0.1.0-py3-none-any.whl -
Subject digest:
88eaa3e40e5367f0b070054aa16ebc31c7c122bcf4f07883978719327a88763a - Sigstore transparency entry: 538478493
- Sigstore integration time:
-
Permalink:
MiKatre/django-turnstile-htmx@7b1ad8c431e1c3e24d589a4f95d80d1dc14465f4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/MiKatre
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7b1ad8c431e1c3e24d589a4f95d80d1dc14465f4 -
Trigger Event:
release
-
Statement type: