{"id":8117,"library":"django-simple-captcha","title":"Django Simple CAPTCHA","description":"django-simple-captcha is a robust yet easy-to-use Django application for integrating CAPTCHA into forms. It supports various CAPTCHA types including image and audio. Currently at version 0.6.3, it is actively maintained with regular updates to support new Django versions and address user feedback.","status":"active","version":"0.6.3","language":"en","source_language":"en","source_url":"https://github.com/mbi/django-simple-captcha","tags":["django","captcha","security","forms","authentication"],"install":[{"cmd":"pip install django-simple-captcha","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core framework dependency for any Django application.","package":"Django","optional":false},{"reason":"Optional dependency for Django REST Framework integration if DRF API captcha is needed.","package":"djangorestframework","optional":true}],"imports":[{"symbol":"CaptchaField","correct":"from captcha.fields import CaptchaField"},{"symbol":"CaptchaWidget","correct":"from captcha.widgets import CaptchaWidget"}],"quickstart":{"code":"import os\nimport django\nfrom django.conf import settings\n\n# Minimal Django setup for demonstration\nif not settings.configured:\n    settings.configure(\n        INSTALLED_APPS=['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'captcha'],\n        MIDDLEWARE=[\n            'django.middleware.security.SecurityMiddleware',\n            'django.contrib.sessions.middleware.SessionMiddleware',\n            'django.middleware.common.CommonMiddleware',\n            'django.middleware.csrf.CsrfViewMiddleware',\n            'django.contrib.auth.middleware.AuthenticationMiddleware',\n            'django.contrib.messages.middleware.MessageMiddleware',\n            'django.middleware.clickjacking.XFrameOptionsMiddleware',\n        ],\n        ROOT_URLCONF='__main__',\n        TEMPLATES=[\n            {\n                'BACKEND': 'django.template.backends.django.DjangoTemplates',\n                'DIRS': [],\n                'APP_DIRS': True,\n                'OPTIONS': {\n                    'context_processors': [\n                        'django.template.context_processors.debug',\n                        'django.template.context_processors.request',\n                        'django.contrib.auth.context_processors.auth',\n                        'django.contrib.messages.context_processors.messages',\n                    ],\n                },\n            },\n        ],\n        DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},\n        SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-testing-only'),\n        STATIC_URL='/static/',\n        DEBUG=True\n    )\n\ndjango.setup()\n\nfrom django import forms\nfrom django.http import HttpResponse\nfrom django.urls import path, include\nfrom django.views.generic import FormView\nfrom captcha.fields import CaptchaField\n\nclass ContactForm(forms.Form):\n    subject = forms.CharField(max_length=100)\n    message = forms.CharField(widget=forms.Textarea)\n    captcha = CaptchaField()\n\nclass ContactView(FormView):\n    template_name = 'form_template.html' # In a real app, this would be a file\n    form_class = ContactForm\n    success_url = '/success/'\n\n    def form_valid(self, form):\n        # Process the form data (e.g., send email)\n        print(\"Form is valid! Subject:\", form.cleaned_data['subject'])\n        return super().form_valid(form)\n\n    def get(self, request, *args, **kwargs):\n        # For quickstart, just render the form without a real template\n        form = self.get_form()\n        html = f\"\"\"\n            <form method=\"post\">\n                <p>{{ form.subject.label_tag }} {{ form.subject }}</p>\n                <p>{{ form.message.label_tag }} {{ form.message }}</p>\n                <p>{{ form.captcha.label_tag }} {{ form.captcha }}</p>\n                <button type=\"submit\">Submit</button>\n                {% csrf_token %}\n            </form>\n        \"\"\"\n        return HttpResponse(html.replace('{% csrf_token %}', request.META.get('CSRF_COOKIE', '')))\n\n    def post(self, request, *args, **kwargs):\n        form = self.get_form()\n        if form.is_valid():\n            return self.form_valid(form)\n        else:\n            return HttpResponse(\"Form invalid! \" + str(form.errors))\n\nurlpatterns = [\n    path('', ContactView.as_view(), name='contact'),\n    path('captcha/', include('captcha.urls')),\n    path('success/', lambda request: HttpResponse('Form submitted successfully! CAPTCHA was valid.')),\n]\n\n# To run this minimal example (requires a test runner or manual URL dispatch)\n# from django.urls import resolve\n# from django.test import RequestFactory\n# \n# factory = RequestFactory()\n# \n# # Test GET request\n# request = factory.get('/')\n# response = resolve('/').func(request)\n# print(\"\\nGET Response:\", response.status_code, response.content.decode()[:200], \"...\")\n# \n# # Test POST request (replace with actual CAPTCHA values from GET request if needed)\n# # This part is tricky to automate without actually solving the captcha.\n# # You would typically submit a solved captcha value. \n# # Example POST data, assuming 'captcha_0' is the key for the hash, 'captcha_1' for the response:\n# # post_data = {'subject': 'Test Subject', 'message': 'Test Message', 'captcha_0': 'hash_value', 'captcha_1': 'solved_text'}\n# # request = factory.post('/', post_data)\n# # response = resolve('/').func(request)\n# # print(\"\\nPOST Response:\", response.status_code, response.content.decode()[:200], \"...\")\n\nprint(\"Setup complete. You would normally run this via `manage.py runserver`.\")\nprint(\"To access the form, configure your Django project's urls.py with `path('captcha/', include('captcha.urls'))` and `path('', views.ContactView.as_view())`\")","lang":"python","description":"To integrate django-simple-captcha, first add 'captcha' to your `INSTALLED_APPS` in `settings.py`. Then, include `path('captcha/', include('captcha.urls'))` in your project's `urls.py`. Finally, define a form using `captcha.fields.CaptchaField` and render it in your templates."},"warnings":[{"fix":"Add 'captcha' to `INSTALLED_APPS` in `settings.py` and `path('captcha/', include('captcha.urls'))` to your project's `urls.py`.","message":"Ensure 'captcha' is added to your `INSTALLED_APPS` and `path('captcha/', include('captcha.urls'))` is configured in your project's `urls.py`. Without these, CAPTCHA images or forms will not render correctly, leading to `NoReverseMatch` errors or missing images.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Verify Django's static files configuration. Run `python manage.py collectstatic` in production and ensure `STATIC_URL` is accessible. In development, `DEBUG = True` generally handles serving static files automatically.","message":"By default, the CAPTCHA image relies on Django's static files system. If your static files are not correctly configured (especially in production), the CAPTCHA image might not appear. Ensure `STATIC_URL` and `STATIC_ROOT` are properly set and static files are collected.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Upgrade to version 0.6.1 or newer (`pip install --upgrade django-simple-captcha`). If upgrading is not immediately possible, implement a periodic task to clean up temporary files (e.g., in `os.tempdir`).","message":"Older versions of django-simple-captcha (pre-0.6.1) could leave temporary audio files, potentially filling up disk space. While fixed in 0.6.1, users on older versions should consider upgrading or implementing custom cleanup.","severity":"deprecated","affected_versions":"<0.6.1"},{"fix":"If using DRF features with django-simple-captcha, explicitly install `djangorestframework`: `pip install djangorestframework`.","message":"Version 0.6.2 made `djangorestframework` an optional dependency. If you were relying on DRF integration and upgrading from a version before 0.6.2, ensure `djangorestframework` is explicitly installed if you need it, as it might no longer be pulled in automatically.","severity":"gotcha","affected_versions":">=0.6.2"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Add `path('captcha/', include('captcha.urls'))` to your project's `urls.py` file.","cause":"The CAPTCHA URL patterns are not included in your project's `urls.py`.","error":"django.urls.exceptions.NoReverseMatch: 'captcha' is not a registered namespace"},{"fix":"Ensure `pip install django-simple-captcha` has been run and 'captcha' is in your `settings.INSTALLED_APPS`.","cause":"The `django-simple-captcha` library is either not installed or 'captcha' is missing from `INSTALLED_APPS`.","error":"ModuleNotFoundError: No module named 'captcha.fields'"},{"fix":"Check your `settings.STATIC_URL`, `STATIC_ROOT`. In production, ensure `python manage.py collectstatic` has been run and your web server is configured to serve static files from `STATIC_ROOT` via `STATIC_URL`.","cause":"This is often due to incorrect static files configuration or `DEBUG=False` in development without proper static file serving.","error":"Captcha image not showing/broken link"},{"fix":"Set a secure `SECRET_KEY` in your `settings.py`. For example: `SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'default-in-dev-only')`.","cause":"Django requires a `SECRET_KEY` in `settings.py` for security functions, including session management and CSRF tokens, which CAPTCHA forms implicitly use.","error":"django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty."}]}