{"id":2003,"library":"django-ratelimit","title":"Django Ratelimit","description":"Django Ratelimit is a cache-based rate-limiting library for Django applications, currently at version 4.1.0. It provides decorators and middleware to limit the rate of client requests, helping to prevent abuse and manage server resources. The library typically has an active release cadence, with major versions aligning with Django's own release cycle and minor versions for fixes and features.","status":"active","version":"4.1.0","language":"en","source_language":"en","source_url":"https://github.com/jsocol/django-ratelimit","tags":["django","rate-limiting","cache","security","throttling"],"install":[{"cmd":"pip install django-ratelimit","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core framework dependency for the library's functionality.","package":"Django","optional":false}],"imports":[{"note":"The package was renamed from `ratelimit` to `django_ratelimit` in v4.0.0 to avoid disambiguation issues. All import paths must be updated.","wrong":"from ratelimit.decorators import ratelimit","symbol":"ratelimit","correct":"from django_ratelimit.decorators import ratelimit"},{"note":"As with the `ratelimit` decorator, top-level constants' import paths changed in v4.0.0.","wrong":"from ratelimit import ALL, UNSAFE","symbol":"ALL","correct":"from django_ratelimit import ALL, UNSAFE"}],"quickstart":{"code":"from django.http import HttpResponse\nfrom django.conf import settings\nfrom django.core.cache import cache\nfrom django_ratelimit.decorators import ratelimit\n\n# Ensure Django settings are configured for a cache backend supporting atomic increments\n# (e.g., Memcached or Redis).\n# In a real project, this would be in settings.py\nif not settings.configured:\n    settings.configure(\n        DEBUG=True,\n        SECRET_KEY='a-very-secret-key',\n        CACHES={\n            'default': {\n                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',\n                'LOCATION': 'unique-snowflake',\n            }\n        },\n        ROOT_URLCONF=__name__,\n        INSTALLED_APPS=[\n            'django_ratelimit'\n        ]\n    )\n\n# Clear cache for repeatable testing\ncache.clear()\n\n@ratelimit(key='ip', rate='5/m', block=True)\ndef my_rate_limited_view(request):\n    \"\"\"This view allows 5 requests per minute per IP address.\"\"\"\n    return HttpResponse(\"Hello from a rate-limited view!\")\n\n# Example of how you might test it (not part of typical quickstart)\nif __name__ == '__main__':\n    from django.urls import path\n    from django.test import RequestFactory\n\n    urlpatterns = [\n        path('limited/', my_rate_limited_view),\n    ]\n\n    factory = RequestFactory()\n    for i in range(7):\n        request = factory.get('/limited/')\n        request.META['REMOTE_ADDR'] = '127.0.0.1' # Simulate client IP\n        try:\n            response = my_rate_limited_view(request)\n            print(f\"Request {i+1}: Status {response.status_code}\")\n        except Exception as e:\n            print(f\"Request {i+1}: Blocked (Exception: {type(e).__name__})\")","lang":"python","description":"To use `django-ratelimit`, first ensure you have a Django cache backend configured that supports atomic increment operations (like Memcached or Redis, not the default database cache). Then, apply the `@ratelimit` decorator to your Django views. The `key` parameter determines how requests are grouped (e.g., by 'ip' or 'user'), `rate` defines the limit (e.g., '5/m' for 5 per minute), and `block=True` will return a 429 Too Many Requests response if the limit is exceeded."},"warnings":[{"fix":"Update all `import` statements from `ratelimit` to `django_ratelimit`.","message":"The package name was changed from `ratelimit` to `django_ratelimit` in version 4.0.0. All import statements must be updated accordingly (e.g., `from django_ratelimit.decorators import ratelimit`).","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"To retain the old behavior of only annotating the request, explicitly set `block=False` on the decorator: `@ratelimit(key='ip', rate='5/m', block=False)`.","message":"The default behavior of the `@ratelimit` decorator's `block` argument changed from `False` to `True` in version 4.0.0. Views will now block requests by default if the rate limit is exceeded, instead of just annotating the request.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Ensure your project uses Python 3.7+ and Django 3.2+ when upgrading to `django-ratelimit` 4.0.0 or newer.","message":"Version 4.0.0 dropped support for Python versions older than 3.7 and Django versions older than 3.2.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Configure your Django `CACHES` setting to use a backend like `django.core.cache.backends.memcached.PyMemcacheCache` or `django_redis.cache.RedisCache`.","message":"`django-ratelimit` requires a Django cache backend that supports atomic increment operations (e.g., Memcached or Redis). The database cache backend does *not* support this and will lead to incorrect rate limiting behavior.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For class-based views, wrap `@ratelimit` with `@method_decorator`. Example: `from django.utils.decorators import method_decorator; @method_decorator(ratelimit(key='ip', rate='5/m'), name='dispatch') class MyView(View): ...`","message":"Since version 3.0, the `@ratelimit` decorator no longer directly supports class methods, and `RatelimitMixin` was dropped. Instead, use `@method_decorator` for class-based views.","severity":"deprecated","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}