Skip to content
Myra EU CAPTCHA Online Help Updated · 25 Aug 2026

Django

The myra-eucaptcha-django package supplies a form field, a widget, and a management function for the configurations in the administration area of Django.

Requirements

The following requirements must be met:

Requirement Value
Package manager pip or uv
Access Administration area of Django
Credentials Public sitekey and secret from the Details view

Install the package

Proceed as follows to set up the package:

  • Install the package:
pip install myra-eucaptcha-django

With the uv package manager, the command is as follows:

uv add myra-eucaptcha-django
  • Enter the application in settings.py:
# settings.py
INSTALLED_APPS = [
    ...
    'myra_eucaptcha_django',
]
  • Do the migrations:
python manage.py migrate
  • The administration area shows the Captcha Configurations entry.

Make a configuration

Proceed as follows to make a configuration:

  • In the administration area, open the Captcha Configurations entry.
  • Make a configuration with your sitekey and your secret.
  • Set the configuration to Default, so that forms use it without a name.
  • The configuration is available in the forms.

Put the field in a form

Add the CaptchaField field and CaptchaFormMixin to the form:

from django import forms
from myra_eucaptcha_django import CaptchaField, CaptchaFormMixin

class ContactForm(CaptchaFormMixin, forms.Form):
    name = forms.CharField()
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)

    # Uses the default configuration
    captcha = CaptchaField()

In the view, give the request to the field, so that the field can verify the IP address of the visitor:

from django.shortcuts import render, redirect
from .forms import ContactForm

def contact_view(request):
    if request.method == "POST":
        # Pass request= to enable IP validation
        form = ContactForm(request.POST, request=request)
        if form.is_valid():
            # Process the form
            return redirect("success")
    else:
        form = ContactForm()

    return render(request, "contact.html", {"form": form})

Render the form in the template:

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Send</button>
</form>

The widget supplies the necessary JavaScript itself.

Use more than one configuration

In the administration area, you make more than one configuration with unique names, for example default, contact-form, and registration. In the form, you give the name of the applicable configuration:

class ContactForm(CaptchaFormMixin, forms.Form):
    name = forms.CharField()
    captcha = CaptchaField("contact-form")

class RegistrationForm(CaptchaFormMixin, forms.Form):
    username = forms.CharField()
    captcha = CaptchaField("registration")

class CommentForm(CaptchaFormMixin, forms.Form):
    comment = forms.CharField()
    captcha = CaptchaField()  # Uses default configuration

Fields of a configuration

These fields are available:

Field Default Effect
name necessary Unique name of the configuration.
description Free note about the use.
sitekey necessary Public sitekey for the widget.
secret necessary Secret key for the verification on the server.
is_default False Uses the configuration when the form gives no name.
is_active True Releases the configuration for use.

These fields change the addresses of the services:

Field Default Effect
verify_url https://api.eu-captcha.eu/v1/verify/ Address of the endpoint for the verification.
widget_url https://cdn.eu-captcha.eu/verify.js Address of the script for the widget.

These fields set the time limits in seconds:

Field Default Effect
connect_timeout 3 Time limit for the connection setup.
read_timeout 10 Time limit to read the response.
write_timeout 10 Time limit to send the request.
pool_timeout 3 Time limit for an available connection from the connection pool.

These fields control the behaviour for errors:

Field Default Effect
default_result_on_error True For a network error, gives a positive result and permits the transmission.
suppress_exceptions True Suppresses exceptions and gives the result instead.

Configuration with the settings

Instead of the database, you use the settings.py file:

# settings.py
EUCAPTCHA_SITEKEY = "EUCAPTCHA_SITE_KEY"
EUCAPTCHA_SECRET = "EUCAPTCHA_SECRET_KEY"

# Optional
EUCAPTCHA_VERIFY_URL = "https://api.eu-captcha.eu/v1/verify/"
EUCAPTCHA_WIDGET_URL = "https://cdn.eu-captcha.eu/verify.js"
EUCAPTCHA_CONNECT_TIMEOUT = 3
EUCAPTCHA_READ_TIMEOUT = 10
EUCAPTCHA_WRITE_TIMEOUT = 10
EUCAPTCHA_POOL_TIMEOUT = 3
EUCAPTCHA_DEFAULT_RESULT_ON_ERROR = True
EUCAPTCHA_SUPPRESS_EXCEPTIONS = True

Configurations from the database have precedence over the settings.

Interface

Element Use
CaptchaField(config_name=None, **kwargs) Form field that renders the widget and verifies the response. Without config_name, the default configuration applies.
CaptchaFormMixin Gives the request to the fields, so that the IP address can be verified.
CaptchaWidget Renders the challenge. Usually, you do not use this element directly.
validate_captcha(...) Verifies a token immediately. For an error, the function causes django.core.exceptions.ValidationError.
from myra_eucaptcha_django import validate_captcha

validate_captcha(
    token="captcha-response-token",
    remote_addr="client-ip",  # Optional
    config_name="my-config",  # Optional
)

Full example

See HTML and Django.