2013-06-30 3 views
5

Я пытаюсь интегрироваться с приложением инвентаризации и разрешать пользователям добавлять детали в инвентарь через форму Django. Я могу читать из базы данных инвентаризации, но мне приходится писать через API, поэтому, основываясь на том, что они входят в предыдущую форму, я хочу дать им список доступных частей для добавления.Настройка формы Django Параметры ChoiceField в виде формы

Вот моя форма, я установил несколько вариантов как по умолчанию:

class PartForm(forms.Form): 
    PART_CHOICES = (
    ('BT-J1KND-A', 'BT-J1KND-A'), 
    ('BT-J1KND-B', 'BT-J1KND-B'),) 
    part = forms.ChoiceField(choices = PART_CHOICES,required = True, label = 'Part to add to Inventory') 

А вот где я поставил выбор

parts_list = part_sql(part) 
#build choices 
PART_CHOICES= [(p[0],p[0]) for p in parts_list] 
form = PartForm() 
form.fields['part'].choices = PART_CHOICES 

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

Select a valid choice. BT-J1KND-C is not one of the available choices. 

Как исправить это, чтобы заставить его принять выбранные мной варианты как допустимые параметры?

+0

Приблизительно, сколько вариантов выбора? –

+0

в лучшем случае будет 6 – enderv

ответ

10

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

Для того, чтобы получить запрос обрабатывается правильно, вы должны иметь последовательную PartForm

Вы можете достичь этого плавно изменяя атрибут поля в choices при инициализации.

Например:

class ExampleForm(forms.Form): 
    CHOICES = (
     ('EXMPL', 'Example'), 
    ) 
    field = forms.ChoiceField(choices=CHOICES, required=True, label='Example') 

    def __init__(self, custom_choices=None, *args, **kwargs): 
     super(ExampleForm, self).__init__(*args, **kwargs) 
     if custom_choices: 
      self.fields['field'].choices = custom_choices 

И затем, просто помните, чтобы правильно инициализировать форму, с

form = ExampleForm(my_custom_choices_nested_tuple, ...)

Вы также можете перепроверить, где вы на самом деле обработки данных (a form = PartForm(request.REQUEST), не указано в вашем скопированном коде, я думаю)

+0

Это избавилось от одной ошибки, но теперь у меня есть ошибка значения при попытке обработать данные. ValueError слишком много значений для разблокировки выделенной строки - это строка шаблона, в которой я показываю {{form.as_p}} – enderv

+0

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

+0

'form = PartForm (request.POST) '' if form.is_valid(): 'всегда сбой – enderv

0

Если вы программно измените одно из полей формы, я считаю, что вам нужно позвонить full_clean() на форме после этого, чтобы изменения отражались в форме. Мы делаем это в приложении, над которым я работаю, - вот код, который мы изменили для вашего примера.

from django.forms import Select 

... 

field = form.fields['part'] 
field.choices = PART_CHOICES 
field.widget = Select(choices=PART_CHOICES) 

form.fields['part'] = field 
form.full_clean() 

Обратите внимание, что так же, как и присвоение field.choices, мы также повторно инициализировать field.widget.

+0

, это тоже избавило от ошибки проверки, но теперь у меня есть значение ValueError слишком много значений для распаковки – enderv

+0

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

+0

Большое спасибо – enderv

Смежные вопросы