Skip to content

Commit

Permalink
Add support for Django REST framework's
Browse files Browse the repository at this point in the history
  • Loading branch information
ronanboiteau committed Mar 23, 2024
1 parent e113045 commit b2b4e7a
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions django_ratelimit/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def get_header(request, header):
_ACCESSOR_KEYS = {
'get': lambda r, k: r.GET.get(k, ''),
'post': lambda r, k: r.POST.get(k, ''),
'data': lambda r, k: r.data.get(k, ''),
'header': get_header,
}

Expand Down
15 changes: 15 additions & 0 deletions django_ratelimit/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
from django.utils.decorators import method_decorator
from django.views.generic import View

from rest_framework.decorators import api_view
from rest_framework.test import APIRequestFactory

from django_ratelimit.decorators import ratelimit
from django_ratelimit.exceptions import Ratelimited
from django_ratelimit.core import (get_usage, is_ratelimited,
_split_rate, _get_ip)


rf = RequestFactory()
rest_rf = APIRequestFactory()


class MockUser:
Expand Down Expand Up @@ -152,6 +156,17 @@ def view(request):
assert not view(rf.post('/', {'foo': 'b'}))
assert view(rf.post('/', {'foo': 'b'}))

def test_key_data(self):
@api_view(['POST'])
@ratelimit(key='data:foo', rate='1/m', block=False)
def view(request):
return request.limited

assert not view(rest_rf.post('/', {'foo': 'a'}))
assert view(rest_rf.post('/', {'foo': 'a'}))
assert not view(rest_rf.post('/', {'foo': 'b'}))
assert view(rest_rf.post('/', {'foo': 'b'}))

def test_key_header(self):
def _req():
req = rf.post('/')
Expand Down
1 change: 1 addition & 0 deletions docs/keys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ used ratelimit keys:
<security-chapter>` notes.
- ``'get:X'`` - Use the value of ``request.GET.get('X', '')``.
- ``'post:X'`` - Use the value of ``request.POST.get('X', '')``.
- ``'data:X'`` - Use the value of ``request.data.get('X', '')`` (useful for projects using Django REST Framework).
- ``'header:x-x'`` - Use the value of
``request.META.get('HTTP_X_X', '')``.

Expand Down
1 change: 1 addition & 0 deletions test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

INSTALLED_APPS = (
'django_ratelimit',
'rest_framework',
)

RATELIMIT_USE_CACHE = 'default'
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ deps =
django42: Django>=4.2,<4.3
django50: Django>=5.0a1,<5.1
djangomain: https://github.com/django/django/archive/main.tar.gz
djangorestframework~=3.14.0
pymemcache>=4.0,<5.0
django-redis>=5.2,<6.0
flake8
Expand Down

0 comments on commit b2b4e7a

Please sign in to comment.