Answer the question
In order to leave comments, you need to log in
Ban by IP for a while?
Hello, I have a form (fixed photo) so that after submitting the form, the IP of this person is banned for a while, he can browse the site, but nothing happens when submitting the form, or he gets an error that so much time is left. This is necessary in order to so that all sorts of clever people don’t spam the admin panel with left applications.
Answer the question
In order to leave comments, you need to log in
Подключаете примерно такую мидлварь
def _get_ending(n, endings):
n = n % 100
if n >= 11 and n <= 19:
return endings[2]
else:
n = n % 10
if n == 1:
return endings[0]
elif n > 1 and n < 5:
return endings[1]
else:
return endings[2]
def _get_message(limit):
if limit > 3660:
limit //= 3600
endings = [_('часа'), _('часов'), _('часов')]
elif limit > 60:
limit //= 60
endings = [_('минуты'), _('минут'), _('минут')]
else:
endings = [_('секунды'), _('секунд'), _('секунд')]
return _('Форма отправлялась менее {} {} назад').format(limit, _get_ending(limit, endings))
def post_limit_middleware(get_response):
limits = getattr(settings, 'REQUEST_LIMITS', {})
def middleware(request):
if request.method == 'POST':
match = resolve(request.path_info)
name = '{}:{}'.format(match.namespace, match.url_name) if match.namespace else match.url_name
limit = limits.get(name)
if limit is not None:
now = datetime.now()
user_id = request.user.username if request.user.is_authenticated else get_ip(request)
key = hashlib.md5(user_id.encode()).hexdigest()
cache_name = 'last-request.{0}.{1}'.format(name, key)
last_request = cache.get(cache_name, now - timedelta(days=1))
if (now - last_request) < timedelta(seconds=limit):
cache.set(cache_name, now)
if request.is_ajax():
response = JsonResponse([_get_message(limit)], safe=False)
response.status_code = 429
else:
response = render(request, '429.html', {'message': _get_message(limit)})
response.status_code = 429
return response
else:
cache.set(cache_name, now)
response = get_response(request)
return response
return middleware
REQUEST_LIMITS = {
'contact_form': 3600,
}
If you use cache - I would do it easier. Provided that in ip - ip-address:
from django.core.cache import cache
IP_KEY = 'request_ban:{ip}'
DELAY = 3600
result = cache.get(IP_KEY.format(ip=ip))
if result:
difference = (result - datetime.datetime.now()).seconds
print(f'Вам осталось {difference} секунд')
else:
cache.set(
IP_KEY.format(ip=ip),
datetime.datetime.now() + datetime.timedelta(seconds=DELAY),
DELAY,
)
print('Добро пожаловать!')
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question