У меня есть раскрывающийся список в форме модели, и пользователь не может изменить выбранное значение. Я обнаружил, что disabled
делает именно то, что мне нужно. Однако в этом есть странность:
При первом открытии формы (GET )значение выбрано, и пользователь не может его изменить. это здорово:
Но как только возникает ошибка проверки с unrelated field
и POST отправляет пользователя обратно в ту же форму, предыдущая информация теряется. Выпадающий список отключенного внешнего ключа -больше не содержит никакого значения и очень раздражает.
Я провел некоторое исследование и нашел кое-что в stackoverflow, и кажется, что когда раскрывающийся виджет внешнего ключа -отключен, данные вообще не отправляются обратно. Хотя проверку можно переопределить, чтобы не выдавать никаких ошибок для раскрывающегося поля, как объясняет третий ответ здесь . Однако, если ЛЮБОЕ ДРУГОЕ несвязанное поле выдает ошибку, данные теряются, потому что отключенное раскрывающееся меню никогда не отправляло данные в POST.
Это сложная ситуация.
Есть ли способ передать данные в представлении в request.POST? или что вы предлагаете? Я мог бы использовать readonly
вместо disabled
, и это сработало бы, однако выпадающий список может быть изменен пользователем, что также раздражает.
Любые идеи? Большое спасибо
редактировать:
Небольшая поправка :Данные не полностью потеряны. Скорее выбор неправильно установлен на начальное фиктивное значение.
ОБНОВЛЕНИЕ:
Решение от Фрэнсиса выглядит очень многообещающе. Поэтому я попробовал его второе предложение и добавил скрытое поле ввода в html и передал правильное значение в POST.
Теперь проблема в том, как действовать.Я попытался добавить отсутствующую запись в querydict формы набора форм, например (, чтобы установить правильное раскрывающееся значение )
formset.forms[0].data['form-0-deal_type'] = formset.forms[0].data['form-0-hiddenfield']
. Но там сказаноThis QueryDict instance is immutable
Единственный другой способ сделать это - установить его через Инициалы с обычными наборами форм. К сожалению, я использую наборы моделей, которые не поддерживают инициалы для существующих форм.
Если нет другого решения, я начинаю рефакторинг моего набора моделей в обычный набор форм. Все еще открыты для идей...
Окончательное обновление + решение:
Нет необходимости рефакторить 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 }}
{{fs.deal_type}}
{% endfor %}
{% endif %}
просто творит чудеса... наслаждайтесь:)