В Django один из способов предотвратить отправку одной и той же формы несколько раз — использовать функцию «отключить при отправке» формы Django. Этого можно добиться, добавив в шаблон функцию JavaScript, которая отключает кнопку отправки формы после нажатия на нее.

В шаблоне:

<form id="form" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit" onclick="disableForm()">
</form>
<script>
    function disableForm() {
        document.getElementById("form").submit.disabled = true;
    }
</script>

Другой способ — использовать подход на основе токенов, при котором для формы создается уникальный токен, который связывается с сеансом пользователя. Затем токен передается в форму как скрытое поле. При отправке формы сервер сверяет токен с сеансом пользователя и гарантирует его соответствие перед сохранением данных формы в базе данных. Если токен не совпадает, форма считается повторной отправкой и отклоняется.

В представлениях.py

from django.http import JsonResponse

def get_token(request):
    token = uuid.uuid4().hex
    request.session['form_token'] = token
    return JsonResponse({'token': token})

def submit_form(request):
    if request.method == 'POST':
        token = request.POST.get('token')
        if token == request.session.get('form_token'):
            form = MyForm(request.POST)
            if form.is_valid():
                form.save()
                request.session['form_token'] = None
                return JsonResponse({'status': 'success'})
        return JsonResponse({'status': 'error'})

В шаблоне:

<form id="form" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="hidden" name="token" id="token">
    <input type="submit" value="Submit">
</form>
<script>
    $(document).ready(function() {
        $.get("/get_token/", function(data) {
            $("#token").val(data.token);
        });
    });
</script>

Другой подход заключается в использовании декоратора @atomic или диспетчера контекста transaction.atomic() в представлениях. Это предотвратит отправку одной и той же формы несколько раз путем отката транзакции, если происходит одновременное обновление одних и тех же данных.

from django.db import transaction

@transaction.atomic
def submit_form(request):
    if request.method == 'POST':
        form = MyForm(request.POST)
        if form.is_valid():
            form.save()
            return JsonResponse({'status': 'success'})
    return JsonResponse({'status': 'error'})

Вы можете использовать любой из вышеперечисленных методов, чтобы предотвратить отправку нескольких форм в Django, в зависимости от конкретных требований вашего приложения.

Для существующих проектов я использую последний вариант, а для новых проектов выбираю один из первых двух вариантов.