Отправить форму ChoiceField Django

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

Когда я нажимаю отправить, я получаю __init__() got multiple values for keyword argument 'networkList'.

My forms.py it's:

class SimpleDeploy(forms.Form):
    def __init__(self, networkList, policiesList, applicationList, *args, **kwargs):
        super(SimpleDeploy, self).__init__(*args, **kwargs)
        if networkList and policiesList and applicationList:
            self.fields['Network Partition ID:'] = forms.ChoiceField(choices=networkList)
            self.fields['Application Policy ID:'] = forms.ChoiceField(choices=policiesList)
            self.fields['Application ID:'] = forms.ChoiceField(choices=applicationList)
        else:
            self.fields['Network Partition ID:'] = forms.ChoiceField(choices='No network partitions found')
            self.fields['Application Policy ID'] = forms.ChoiceField(choices='No application policies found')
            self.fields['Application ID:'] = forms.ChoiceField(choices='No applications found')

На моем views.py метод выглядит так:

def simpleDeploy(request):
    netList = getDetailsNetworkPartitions(request)
    polList = getDetailsApplicationPolicies(request)
    appList = getDetailsApplications(request)
    if request.method == 'POST':
        form = SimpleDeploy(request.POST, networkList=None, policiesList=None, applicationList=None)
        if form.is_valid():
            network = form.cleaned_data['Network Partition ID:']
            policy = form.cleaned_data['Application Policy ID:']
            application = form.cleaned_data['Application ID:']
            ##### more things
        else:
            simpleForm = SimpleDeploy(networkList=netList, policiesList=polList, applicationList=appList)
    else:
        simpleForm = SimpleDeploy(networkList=netList, policiesList=polList, applicationList=appList)
    return render(request, 'apacheStratos/simpleDeploy.html', {'form': simpleForm})

Ошибка трассировки:

Traceback:
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/iago/Escritorio/tfm/website/apacheStratos/views.py" in simpleDeploy
  60.         form = SimpleDeploy(request.POST, networkList=None, policiesList=None, applicationList=None)

Exception Type: TypeError at /stratos/simpleDeploy
Exception Value: __init__() got multiple values for keyword argument 'networkList'

Глядя на документ, я прочитал, что запрос POST это всегда первый параметр (request.Post), а в методе инициализации я думаю, что он соответствует self, более того, на других ответах здесь я видел, что иногда установка data=params работает, но в моем случае я получить ошибку: need more than 1 value to unpack в строке if form.is_valid():

Проследить:

File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/iago/Escritorio/tfm/website/apacheStratos/views.py" in simpleDeploy
  61.         if form.is_valid():
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/forms/forms.py" in is_valid
  184.         return self.is_bound and not self.errors
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/forms/forms.py" in errors
  176.             self.full_clean()
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/forms/forms.py" in full_clean
  392.         self._clean_fields()
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/forms/forms.py" in _clean_fields
  407.                     value = field.clean(value)
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/forms/fields.py" in clean
  163.         self.validate(value)
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/forms/fields.py" in validate
  868.         if value and not self.valid_value(value):
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.12-py2.7.egg/django/forms/fields.py" in valid_value
  878.         for k, v in self.choices:

Exception Type: ValueError at /stratos/simpleDeploy
Exception Value: need more than 1 value to unpack

Итак, в чем моя ошибка? Спасибо и привет.


person Aker666    schedule 18.07.2016    source источник


Ответы (1)


Вы определили свою форму init так, что первый позиционный аргумент равен networkList; поэтому, когда вы выполняете form = SimpleDeploy(request.POST, networkList=None...), и позиционный аргумент, и ключевое слово arg переходят к одному и тому же имени, что недопустимо.

Не меняйте подпись вообще; получить дополнительные значения от kwargs.

def __init__(self, *args, **kwargs):
    networkList = kwargs.pop('networkList', None)
    policiesList = kwargs.pop('policiesList', None)
    applicationList = kwargs.pop('applicationList', None)
    super(...)

В качестве альтернативы, поскольку вам нужны только эти значения внутри формы, вы можете просто передать запрос этому методу и получить эти значения непосредственно там; будет применяться тот же синтаксис.

person Daniel Roseman    schedule 18.07.2016
comment
Привет Даниил, спасибо за ваш ответ. Я изменил подпись, как вы предложили, и теперь работает. Но мне по-прежнему требуется более 1 значения для распаковки в строке, если form.is_valid(): ошибка. В данных сообщения я вижу, что значения верны: (Значение переменной) Идентификатор сетевого раздела: u'network-partition-2' Идентификатор приложения: u'eb2ed6ea-922f-2e56-0129-c0e1c1899ec5' Идентификатор политики приложения: u' application-policy-2' csrfmiddlewaretoken u'BxsGuIE0iI80wJBkTEXF0sIEmLWXfn2t' Или мне нужно также передать кортеж? Спасибо. - person Aker666; 18.07.2016
comment
Вы должны показать, что возвращают getDetailsNetworkPartitions и подобные функции. Выбор должен быть серией из двух кортежей; вы просто возвращаете простой список? - person Daniel Roseman; 18.07.2016
comment
На подаче да. Поскольку мне нужны значения, которые выбрал пользователь, но когда я заполняю форму getDetailsNetworkPartitions (запрос), getDetailsApplicationPolicies (запрос), getDetailsApplications (запрос), они возвращают кортеж, например (u'network-partition-2', u'network- раздел-2'). При отправке, читая другие ответы, вы получаете первый элемент кортежа (идентификатор выбранного варианта), или я неправильно понял? Это тоже должен быть кортеж? - person Aker666; 18.07.2016
comment
Я не понимаю вашего комментария, извините. Выбор есть выбор, это не имеет значения, находитесь ли вы в подчинении, нет. - person Daniel Roseman; 18.07.2016
comment
Мммм, чтобы заполнить форму, 3 функции возвращают кортеж ('id', 'display_name'). Я не получаю ошибку при отображении шаблона, ошибка возникает, когда я нажимаю отправить. - person Aker666; 18.07.2016
comment
Но вы передаете их как None при отправке. Почему? Как вы можете ожидать, что это сработает? - person Daniel Roseman; 18.07.2016
comment
Извините, я новичок в Django. Я думал, что, поскольку я заполнил поля выбора раньше при рендеринге шаблона, мне не нужно было снова передавать данные при отправке, потому что, когда вы нажимаете кнопку «Отправить», форма уже заполнялась ранее. Теперь это работает. Спасибо за вашу помощь и терпение! - person Aker666; 18.07.2016