Once I had to use someone else's django-app, in which there were many forms, methods and everything else. And, of course, the author decided not to bother and not to do any protection against spammers, or from those who like to press F5 on a heavy form. I didn’t have the desire to rewrite and fork, so I decided to write middleware, cutting oxygen to bad people.
Functional
- maintenance mode, allows you to turn off the view as a whole, or individual http methods
- global fallback timeouts of the site for PATCH, POST, etc.
- local timeouts for the view as a whole, or for individual http methods
It's easier to show an example of a config:
DJANGO_THROTTLING = { 'all': 1000, 'post': 'callable:helpers.trash.my_callback', 'congestion': 'forum.views.congestion', 'django.contrib.admin.options.change_view': { 'post': False, 'all': None, 'uri': '/admin/forum/post/23/', }, }
Other examples with the description under a cat.
Installation
git clone http://github.com/night-crawler/django-throttling.git cd django-throttling python setup.py install
Global throttling
The config consists of sections, the topmost one is a fallback, applied to the entire site as a whole, in case no more detailed rule was found.
')
DJANGO_THROTTLING = { 'all': 1000, 'post': 10000, 'congestion': 'forum.views.congestion', }
In this example, for requests of all types the limit is set to 1 request per second, post - request once every 10 seconds.
congestion can be uri, or view. In this case, the neighborhood living view will be called:
def congestion(request, congestion_bundle): user = request.user progress = int(float(congestion_bundle['delta']) / congestion_bundle['timeout'] * 100) c = Context({'user': user, 'congestion_bundle': congestion_bundle, 'progress': progress}) return render_to_response(get_theme_template(user, 'congestion.html'), c, context_instance=RequestContext(request) )
This will allow the user to say that he is naughty and, for example, must wait N seconds. You can provide a view with a script with a progress bar that automatically populates the form. The original view and the entire set of its arguments are transferred to the
congestion_bundle so that something more detailed can be said to the user.
You can disable POST on the entire site. Then the user will see the HttpResponseBadRequest:
DJANGO_THROTTLING = { 'all': 1000, 'post': False, 'congestion': 'forum.views.congestion', }
And you can disable POST like this, then the user will go to the root:
DJANGO_THROTTLING = { 'all': 1000, 'post': '/', 'congestion': 'forum.views.congestion', }
If a simple redirect is not enough, you can make your handler for maintenance-mode:
DJANGO_THROTTLING = { 'all': 1000, 'post': 'forum.views.maintenance', 'congestion': 'forum.views.congestion', }
It may be that you need to block the view only in certain cases, for example, to block one topic in the forum, or for some other particular case. Then you can write a custom handler for the rule:
DJANGO_THROTTLING = { 'all': 1000, 'post': 'callable:helpers.trash.my_callback',
It must return a tuple of key name and timeout. The timeout may again be int (), False, view, or uri.
Local throttling
Basically it has the same syntax. It differs only in the presence of the optional key 'uri', which allows you to set the throttle check only on it.
DJANGO_THROTTLING = { 'all': 1000, 'post': 'callable:helpers.trash.my_callback', 'congestion': 'forum.views.congestion', 'django.contrib.admin.options.change_view': { 'post': False, 'all': None, 'uri': '/admin/forum/post/23/',
There are several settings:
- DJANGO_THROTTLING_ENABLED : enables throttling, disabled by default.
- DJANGO_THROTTLING_CACHE_EXPIRE : determines how many keys are stored in the cache. The default is 60 * 60.
- DJANGO_THROTTLING_CACHE_PREFIX : cache prefix, default is "THROTTLING"
- THROTTLING_CACHE_KEY_PATTERNS : patterns for key generation are stored here. In total there are 4 types: view_method, view, site_method, site. You can override.
- DJANGO_THROTTLING_IGNORE_ADMIN : disables throttling if the user is admin. Respectively, requires connected auth
There is a description in English on
github .