Банить по IP на время?
Подключаете примерно такую мидлварь
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
Прописывается в settings.py настройку вида
REQUEST_LIMITS = {
    'contact_form': 3600,
}
И живёте спокойно.
Если используете кеш - я бы поступил проще. При условии что в ip - ip-адрес:
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('Добро пожаловать!')