Registry / web-framework / django-axes

django-axes

JSON →
library8.3.1pypypi✓ verified 25d ago

django-axes is a Django plugin that actively monitors and tracks suspicious login attempts, helping to protect Django-powered sites from brute-force attacks. It can lock out users or IP addresses after a configurable number of failed attempts, supporting various tracking methods like IP, username, and user agent combinations. The library is currently at version 8.3.1 and is actively maintained by the Jazzband community, with a regular release cadence.

pip install django-axes
INSTALL
IMPORT
SIG · DJANGO-AXES
D
django-axes
web-frameworkpythonv8.3.1
Install
3.6s avg
Import
110ms
Disk
66MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v8.3.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.114s · 66.9MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 3.6s · import 0.106s · 67MB
66MB installed
● package 66MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

version
from axes import version
from axes.backends import AxesStandaloneBackend

To quickly set up django-axes, add 'axes' to `INSTALLED_APPS`, configure `AUTHENTICATION_BACKENDS` to include `AxesStandaloneBackend` at the top, and add `AxesMiddleware` to your `MIDDLEWARE` list, preferably at the end. Finally, run `migrate` to create necessary database tables and `check` to verify your configuration. You can then adjust settings like `AXES_FAILURE_LIMIT` and `AXES_COOLOFF_TIME`.

# settings.py INSTALLED_APPS = [ # ... other Django apps 'axes', ] AUTHENTICATION_BACKENDS = [ 'axes.backends.AxesStandaloneBackend', # Must be first 'django.contrib.auth.backends.ModelBackend', ] MIDDLEWARE = [ # ... other Django middleware 'axes.middleware.AxesMiddleware', # Should be last if overriding auth response ] # Optional: Basic configuration AXES_FAILURE_LIMIT = 5 AXES_COOLOFF_TIME = 60 # In minutes or timedelta object (e.g., timedelta(minutes=30)) # AXES_LOCK_OUT_BY_IP_OR_USERNAME = True # Lock out by IP or username, not both # Then, run migrations: # python manage.py migrate # And check your configuration: # python manage.py check
Debug
Known issues
breakingVersion 8.0.0 moved all database-related logic into `axes.handlers.database.AxesDatabaseHandler`. If you had custom handlers or directly accessed internal database functions related to attempts, you will need to refactor your code to use the new handler methods.
fix
Review `axes.handlers.database.AxesDatabaseHandler` for new API calls and refactor any custom logic. Refer to the upgrade notes for specific changes.
affects: 8.0.0+
breakingVersion 7.0.0 introduced significant breaking changes related to dynamic cooloff time calculation and lockout response handling. The lockout response calculation changed to request flagging instead of throwing exceptions, and `axes.request.AxesHttpRequest` object type definition was deprecated.
fix
Consult the version 7 upgrade notes in the official documentation. This will likely involve changes if you customized lockout responses or relied on the deprecated `AxesHttpRequest` object.
affects: 7.0.0+
gotchaAs of version 7.0.2, `AXES_USERNAME_FORM_FIELD` now defaults to `settings.AUTH_USER_MODEL.USERNAME_FIELD`. Previously, it hardcoded to 'username'. If you use a custom user model with a different username field or a custom login form with a non-standard username field name (e.g., 'email'), you must explicitly set `AXES_USERNAME_FORM_FIELD` in your `settings.py` to prevent `AccessAttempt` records from having a `None` username.
fix
Explicitly define `AXES_USERNAME_FORM_FIELD = 'your_username_field_name'` in `settings.py` to match your user model's `USERNAME_FIELD` or your login form's username field.
affects: 7.0.2+
gotchaIncorrect order of `AUTHENTICATION_BACKENDS` can lead to axes not functioning correctly. `AxesStandaloneBackend` (or `AxesBackend`) *must* be the first item in your `AUTHENTICATION_BACKENDS` list in `settings.py`.
fix
Ensure `AUTHENTICATION_BACKENDS = ['axes.backends.AxesStandaloneBackend', 'django.contrib.auth.backends.ModelBackend', ...]`.
affects: All versions
gotchaIf using a multi-process server (e.g., Gunicorn with multiple workers) or a distributed environment, using `django.core.cache.backends.locmem.LocMemCache` or `FileBasedCache` as your cache backend can lead to inconsistent behavior for Axes, as attempts might not be shared across processes.
fix
Configure a persistent and shared cache backend like Memcached or Redis (`django.core.cache.backends.memcached.MemcachedCache`, `django.core.cache.backends.redis.RedisCache`) for accurate tracking across multiple processes.
affects: All versions
gotchaPrior to version 5.32, a common behavior was that the cool-off timer would reset on any subsequent failed login attempts during an existing lockout period. This could inadvertently extend the lockout time indefinitely.
fix
Upgrade to `django-axes` 5.32 or newer and set `AXES_RESET_COOL_OFF_ON_FAILURE_DURING_LOCKOUT = False` in your `settings.py` to prevent the cool-off period from resetting.
affects: < 5.32
Upgrade
Version history
8.3.1latest on PyPI · released Feb 11, 2026
Audit
Dependencies
DjangorequiredCore framework dependency. django-axes 8.x supports Django 4.2, 5.2, and 6.0, and requires Python >= 3.10. Ensure your Django version is supported by the specific django-axes release you are using.
django-ipwareoptionalUsed by default for client IP address detection. While not a hard dependency, it provides robust IP resolution capabilities. If not installed, you might need to configure custom IP resolution.
Agent activity
34 hits · last 30 days
node
28
Amazon
1
OpenAI (training)
1
Resources
django-axes — pip install django-axes · libregistry