У меня есть выпадающее меню в модели, и пользователь не должен изменять выбранное значение.
Я обнаружил, что disabled
делает именно то, что мне нужно. Однако есть странность:
При первом открытии формы (GET) это значение выбирается, и пользователь не может изменить значение. что здорово:
Но как только появляется ошибка проверки с unrelated field
, и POST отправляет пользователя обратно в ту же форму, предыдущая информация теряется. Выключенный выпадающий файл foreignkey больше не содержит никакой ценности и очень раздражает.
Я провел некоторое исследование и нашел что-то в 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 %}
просто творит чудеса... наслаждайтесь:)