Django: перенаправление на текущую страницу после метода POST показывает повторное сообщение

Я так запутался в проблеме, которая у меня есть, я хочу, чтобы кто-то мог указать на мою ошибку.

У меня есть метод в views.py, который привязан к шаблону, который имеет в нем форму. Код выглядит следующим образом:

def template_conf(request, temp_id):
    template = ScanTemplate.objects.get(id=int(temp_id))
    if request.method == 'GET':
        logging.debug('in get method of arachni.template_conf')    
        temp_form = ScanTemplateForm(instance=template))
        return render_response(request, 'arachni/web_scan_template_config.html', 
                               {
                                'template': template,
                                'form': temp_form,
                               })
    elif request.method == 'POST':
        logging.debug('In post method')
        form = ScanTemplateForm(request.POST or None, instance=template)
        if form.is_valid():
            logging.debug('form is valid')
            form.save()
            return HttpResponseRedirect('/web_template_conf/%s/' %temp_id)

Поведение этой страницы таково: когда я нажимаю кнопку "отправить", программа входит в ветвь POST и успешно выполняет все в ветке. Затем HttpResponseRedirect перенаправляется только на текущую страницу (этот url является текущим url, я думаю, должен быть равен .). После этого ветвь GET получилась выполненной, так как я перенаправляюсь на текущую страницу, и страница успешно вернулась. Однако, если я обновляю страницу в это время, браузер возвращает предупреждение о подтверждении:

The page that you're looking for used information that you entered. 
Returning to that page might cause any action you took to be repeated. 
Do you want to continue?

Если я подтвержу, данные сообщения будут снова отправлены на сервер. Похоже, браузер все еще держит предыдущие данные POST. Я не знаю, почему это происходит, пожалуйста, помогите. Спасибо.

Ответ 1

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

# Assuming Django 1.3+
from django.shortcuts import get_object_or_404, render_to_response

def template_conf(request, temp_id):
    template = get_object_or_404(ScanTemplate, pk=temp_id)
    temp_form = ScanTemplateForm(request.POST or None, instance=template)

    if request.method == 'POST':
        if form.is_valid():
            form.save()
            # optional HttpResponseRedirect here
    return render_to_response('arachni/web_scan_template_config.html', 
           {'template': template, 'form': temp_form})

Это просто сохранит вашу модель и повторно отобразит представление. Если вы хотите перенаправить HttpResponse на другой вид после вызова .save(), это не приведет к тому, что браузер предупредит вас, что данные POST должны быть повторно отправлены.

Кроме того, нет необходимости, и это не очень хорошая практика - жестко закодировать ваши шаблоны URL-адресов, к которым вы будете перенаправлять. Используйте метод reverse из django.core.urlresolvers. Это сделает ваш код намного проще для рефакторинга позже, если ваши URL-адреса должны измениться.

Ответ 2

Похоже, вы сталкиваетесь с ошибкой в ​​Chrome 25 (см. Chromium issue 177855), которая неправильно обрабатывает перенаправление обработки. Он исправлен в Chrome 26.

Исходный код правильный, хотя его можно немного упростить, как предлагает Брэндон. Я рекомендую вам перенаправить после успешного почтового запроса, так как это предотвращает случайную повторную отправку данных пользователям (если у их браузера ошибка!).