Если предыдущий ответ не был достаточно простым, я попытаюсь ответить 1) еще раз:
- Как я могу заставить ModelMultipleChoiceField принимать эти «начальные» значения?
Вы можете оставить Action_Form
, как это было в исходном вопросе, и просто использовать это, чтобы сделать именно то, что вы хотите:
>>> form4 = Action_Form(initial={'from_company': Contact.objects.all().values_list('id',flat=True)})
>>> print form4['from_company']
Ну, это будет первый раз, когда я отвечу на свой вопрос, но я нашел решение, и (хотя это явно хак) оно работает.
Вместо получения начального значение из экземпляра формы - self.fields ['что угодно']. initial
кажется None
внутри конструктора, я получаю значение из аргумента ключевого слова "initial". И затем я установил его как единственный вариант для поля «mock». Примерно так:
from django import forms
_choices = ['to be', 'not to be']
class SomeForm(forms.Form):
field = forms.ChoiceField(choices=[(item, item) for item in _choices],
widget=forms.HiddenInput()) # the real field
mock_field = forms.ChoiceField(required=False, # doesn't get submitted
choices=[(item, item) for item in _choices],
label="The question",
widget=forms.Select(attrs={'disabled':'disabled'}))
def __init__(self, *args, **kwargs):
super(SomeForm, self).__init__(*args, **kwargs)
mock_initial = kwargs['initial']['field']
self.fields['mock_field'].choices = [(mock_initial, mock_initial),]
Это, вероятно, требует обработки ошибок. Очевидно, это не сработает, если начальное значение не предоставлено для фактического поля
.
Браузеры не отправляют отключенные поля с помощью POST.
Вы можете попытаться скопировать исходное значение поля field
в mock_field
в форме __init __
def __init__(self, *args, **kwargs):
super(SomeForm, self).__init__(*args, **kwargs)
mock_initial = self.fields['field'].initial
self.fields['mock_field'].initial = mock_initial
Код не тестировался. Обычно вас также беспокоит form.data
, но в этом случае он не будет отличаться от initial