Django: отключенный Dropdown не отправляет информацию обратно в POST

У меня есть выпадающее меню в модели, и пользователь не должен изменять выбранное значение. Я обнаружил, что disabled делает именно то, что мне нужно. Однако есть странность:

При первом открытии формы (GET) это значение выбирается, и пользователь не может изменить значение. что здорово:

enter image description here

Но как только появляется ошибка проверки с unrelated field, и POST отправляет пользователя обратно в ту же форму, предыдущая информация теряется. Выключенный выпадающий файл foreignkey больше не содержит никакой ценности и очень раздражает.

enter image description here

Я провел некоторое исследование и нашел что-то в stackoverflow и, кажется, когда отключен виджет выпадающего меню, данные вообще не отправляются. Хотя проверка может быть переопределена, чтобы не выдавать никаких ошибок для раскрывающегося поля, как объясняет третий ответ здесь . Однако, если ЛЮБОЕ ДРУГОЕ несвязанное поле выдает ошибку, данные теряются, потому что отключенное выпадающее меню никогда не отправляло данные на POST на первом месте.

Это сложная ситуация.

Есть ли способ передать данные в представлении на запрос .POST? или что вы предлагаете? Я мог бы использовать readonly вместо disabled, и это сработает, однако выпадающее меню может быть изменено пользователем, что также раздражает.

Любые идеи? Большое спасибо

изменить

Небольшая коррекция: данные не полностью потеряны. Скорее, выбор ошибочно установлен на исходное значение фиктивного значения.

    <select id="id_form-0-deal_type" name="form-0-deal_type" disabled="disabled">
      <option selected="selected" value="">---------</option>
      <option value="1">deal 1</option>
      <option value="2">deal 2</option>
    </select>

UPDATE:

Решение от Фрэнсиса выглядит очень многообещающим. Поэтому я попробовал свое второе предложение и добавил скрытое поле ввода в html и передал правильное значение в POST.

Теперь проблема в том, как действовать. Я попытался добавить отсутствующую запись в форму запроса formdict, как это (чтобы установить правильное значение выпадающего списка)

formset.forms[0].data['form-0-deal_type'] = formset.forms[0].data['form-0-hiddenfield'] 

Но он говорит This QueryDict instance is immutable

Единственный способ сделать это - установить Initials с помощью обычных форм. К сожалению, я использую modelformsets, который не поддерживает инициалы для существующих форм.

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

Окончательное обновление + решение:

Нет необходимости реорганизовать modelformset в регулярные fomsets. На самом деле я очень не рекомендую это делать, поскольку он приносит другие проблемы с собой. modelformsets обрабатывают все для вас и заполняют недостающие части.

Фактическая проблема заключается в том, что QueryDict неизменяемы, но это можно легко решить, скопировав их:

formset = deal_formset(request.POST, queryset=formset_query)        
if formset.is_valid():
  pass
else:
  new_post = request.POST.copy()
  deal_types = dict()
  for k,v in new_post.items():
     if k.startswith('hidden'):
        deal_types[k[7:]]= v
  for k,v in deal_types.iteritems():
     new_post[k] = v
  formset = deal_formset(new_post, queryset=formset_query)

Это плюс решение Фрэнсиса:

{{ formset.management_form }}
  {% for fs in formset %}  
     {{ fs.id }} 
     <input type="hidden" name="hidden-{{ fs.prefix }}-deal_type" value="{{fs.deal_type.value}}" />
   {{fs.deal_type}}
{% endfor %}
{% endif %}

просто творит чудеса... наслаждайтесь:)

Ответ 1

Это не предмет джанго, его HTML-вещь. Отключенные элементы формы не отправляются по форме.

[Элемент] не может принимать пользовательский ввод, и его значение не будет представлено в форме.

http://www.w3.org/TR/html401/interact/forms.html#h-17.12.1 и http://www.w3schools.com/tags/att_input_disabled.asp p >

вы могли бы использовать readonly, если его в текстовой или текстовой области http://www.w3schools.com/tags/att_input_readonly.asp

что-то еще, что вы можете сделать, показывает значение открытого текста и представляет его как скрытое поле....

{{ form.field_name.label_tag }}
{{ form.field_name.value }}
<input type="hidden" name="field_name" value="{{form.field_name.value}}" />

его не очень элегантно, но он может попасть туда.

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

некоторый образец JQuery:

//Untested, but you get the gist
$(':disabled').each(
    function()
    {
        $(this).after('<input type="hidden" name="' + $(this).attr('name') + '" value="' + $(this).val() + '" />');
    }
);

Ответ 2

Ну, вы можете установить элемент со скрытым свойством в шаблоне, используя формы в представлении для создания формы:

{{form.field.as_hidden}}

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

Ответ 3

Я думаю, что это проблема HTML, а не Django, отключенные поля формы не возвращают свои значения, поэтому вы теряете значение.

Можно ли перегрузить значение в поле, если проверка не выполнена? Вы можете попробовать что-то вроде

if form.is_valid(): # All validation rules pass
    #save form, redirect, etc.
else:
    form.disabled_field = my_value
return render(request, 'contact.html', {'form': form,})

Очевидно, вам нужно будет заменить имя и значение поля правильными данными из вашей модели.