{"id":21223746,"url":"https://github.com/zmh-program/django-turnstile","last_synced_at":"2025-07-10T14:30:48.083Z","repository":{"id":65099545,"uuid":"581837168","full_name":"zmh-program/django-turnstile","owner":"zmh-program","description":"🛡 Add Cloudflare Turnstile widget to the forms of your django project. 🛡 添加 Cloudflare Turnstile 无感验证码小组件到你的 django 项目的表单中","archived":false,"fork":false,"pushed_at":"2024-10-17T12:25:04.000Z","size":8,"stargazers_count":54,"open_issues_count":2,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-05T14:22:18.048Z","etag":null,"topics":["cloudflare-turnstile","django","form","validator"],"latest_commit_sha":null,"homepage":"https://deeptrain.net/login","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zmh-program.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-24T14:25:41.000Z","updated_at":"2025-03-27T20:51:09.000Z","dependencies_parsed_at":"2024-11-20T22:54:55.607Z","dependency_job_id":"bf4c5fe8-c254-4025-bcd9-ed59addcabe1","html_url":"https://github.com/zmh-program/django-turnstile","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/zmh-program/django-turnstile","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmh-program%2Fdjango-turnstile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmh-program%2Fdjango-turnstile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmh-program%2Fdjango-turnstile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmh-program%2Fdjango-turnstile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zmh-program","download_url":"https://codeload.github.com/zmh-program/django-turnstile/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmh-program%2Fdjango-turnstile/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264590771,"owners_count":23633638,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-turnstile","django","form","validator"],"created_at":"2024-11-20T22:53:16.739Z","updated_at":"2025-07-10T14:30:48.078Z","avatar_url":"https://github.com/zmh-program.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"================\nDjango Turnstile\n================\n\nAdd Cloudflare Turnstile validator widget to the forms of your django project.\n\nThis project refers to github project django-hcaptcha (author: AndrejZbin)\n\nConfiguration\n-------------\n\nAdd \"turnstile\" to your INSTALLED_APPS setting like this::\n\n    INSTALLED_APPS = [\n        ...\n        'turnstile',\n    ]\n\nFor development purposes no further configuration is required. By default, django-Turnstile will use dummy keys.\n\nFor production, you'll need to obtain your Turnstile site key and secret key and add them to you settings::\n\n    TURNSTILE_SITEKEY = '\u003cyour sitekey\u003e'\n    TURNSTILE_SECRET = '\u003cyour secret key\u003e'\n\n\nYou can also configure your Turnstile widget globally (`see all options \u003chttps://developers.cloudflare.com/turnstile\u003e`_)::\n\n    TURNSTILE_DEFAULT_CONFIG = {\n        'onload': 'name_of_js_function',\n        'render': 'explicit',\n        'theme': 'dark',  # do not use data- prefix\n        'size': 'compact',  # do not use data- prefix\n        ...\n    }\n\nIf you need to, you can also override default turnstile endpoints::\n\n\n    TURNSTILE_JS_API_URL = 'https://challenges.cloudflare.com/turnstile/v0/api.js'\n    TURNSTILE_VERIFY_URL = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'\n\nUse proxies::\n\n     TURNSTILE_PROXIES = {\n        'http': 'http://127.0.0.1:8000',\n     }\n\nChange default verification timeout::\n\n    TURNSTILE_TIMEOUT = 5\n\n\n\nUsage\n-----------\n\nSimply add TurnstileField to your forms::\n\n    from turnstile.fields import TurnstileField\n\n    class Forms(forms.Form):\n        ....\n        turnstile = TurnstileField()\n        ....\n\nIn your template, if you need to, you can then use `{{ form.turnstile }}` to access the field. \n\nYou can override default config by passing additional arguments::\n\n    class Forms(forms.Form):\n        ....\n        turnstile = TurnstileField(theme='dark', size='compact')\n        ....\n\n\nHow it Works\n------------------\n\nWhen a form is submitted by a user, Turnstile's JavaScript will send one POST parameter to your backend: `cf-turnstile-response`. It will be received by your app and will be used to complete the `turnstile` form field in your backend code.\n\nWhen your app receives these two values, the following will happen:\n \n - Your backend will send these values to the Cloudflare Turnstile servers\n - Their servers will indicate whether the values in the fields are correct\n - If so, your `turnstile` form field will validate correctly\n \nUnit Tests\n--------------\nYou will need to disable the Turnstile field in your unit tests, since your tests obviously cannot complete the Turnstile successfully. One way to do so might be something like:\n\n.. code-block:: python\n\n    from unittest.mock import MagicMock, patch\n\n    from django.test import TestCase\n\n    @patch(\"turnstile.fields.TurnstileField.validate\", return_value=True)\n    class ContactTest(TestCase):\n        test_msg = {\n            \"name\": \"pandora\",\n            \"message\": \"xyz\",\n            \"turnstile\": \"xxx\",  # Any truthy value is fine\n        }\n\n        def test_something(self, mock: MagicMock) -\u003e None:\n            response = self.client.post(\"/contact/\", self.test_msg)\n            self.assertEqual(response.status_code, HTTP_302_FOUND)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzmh-program%2Fdjango-turnstile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzmh-program%2Fdjango-turnstile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzmh-program%2Fdjango-turnstile/lists"}