【问题标题】:Dynamically populating choicefield in Django在 Django 中动态填充选择字段
【发布时间】:2014-10-13 18:20:26
【问题描述】:

我无法在views.py 中初始化Choicefield 表单。我尝试在__init__ 函数中传递option 变量,但出现错误:

__init__() takes at least 2 arguments (1 given)` coming from the `form = super(SomeeWizard, self).get_form(step, data, files)

forms.py

class SomeForm(forms.Form):
        def __init__(self, choice, *args, **kwargs):
            super(SomeForm, self).__init__(*args, **kwargs)
            self.fields['choices'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in choice])

views.py

class SomeWizard(SessionWizardView):

    def get_form(self, step=None, data=None, files=None):
        form = super(SomeWizard, self).get_form(step, data, files)

        if step == "step2":
            option = self.get_cleaned_data_for_step("step1")['choice']

            choice = Choice.objects.filter(question__text__exact=option)

            form = SomeForm(choice)

        return form

    def get_template_names(self):
        return [TEMPLATES[self.steps.current]]

    def done(self, form_list, **kargs):
        return render_to_response('done.html')

编辑

我尝试了 Hasan 解决方案,Django 表单向导将 {'files': None, 'prefix': 'step2', 'initial': {}, 'data': None} 传递到 __init____init__ 函数中的 **kwargSomeForm

我打印了**kwarg中的内容,我得到了:

{'files': None, 'prefix': 'step2', 'initial': {}, 'data': None} {'choices': [<Choice: Blue>, <Choice: Red>]}

【问题讨论】:

  • 请发布完整的回溯。

标签: python django django-forms choicefield


【解决方案1】:

试试这个改变(我评论改变的行):

forms.py:

class SomeForm(forms.Form):
    def __init__(self, *args, **kwargs): #this line changed
        choice = kwargs.pop('choice', None) #this line added
        self.fields['choices'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in choice])
        super(SomeForm, self).__init__(*args, **kwargs)

views.py:

class SomeWizard(SessionWizardView):

    def get_form(self, step=None, data=None, files=None):
        form = super(SomeWizard, self).get_form(step, data, files)

        if step == "step2":
            option = self.get_cleaned_data_for_step("step1")['choice']

            choice = Choice.objects.filter(question__text__exact=option)

            form = SomeForm(choice=choice) #this line changed

        return form

    def get_template_names(self):
        return [TEMPLATES[self.steps.current]]

    def done(self, form_list, **kargs):
        return render_to_response('done.html')

【讨论】:

  • 我得到了'NoneType' object is not iterable,然后我尝试在choice = kwargs.pop('choice', None) 中删除None,并得到KeyErrorchoice
  • 出现此错误是因为choice = Choice.objects.filter(question__text__exact=option) 返回None
  • 对于 KeyError,它与在 kwarg 中传入 {'files': None, 'prefix': 'step2', 'initial': {}, 'data': None} 的 Django 表单向导有关。我似乎无法弄清楚如何阻止它。
  • 检查您的 option 变量。并检查有Choice 对象与uestion__text__exact=option 过滤器?
  • 检查了 optionChoice 变量,它们看起来很好。
【解决方案2】:

仅供参考,我必须使用 data 属性初始化表单才能使其正常工作。例如:

class SomeWizard(SessionWizardView):

    def get_form(self, step=None, data=None, files=None):
        form = super(SomeWizard, self).get_form(step, data, files)

        # determine the step if not given
        if step is None:
            step = self.steps.current

        if step == "2":
            option = self.get_cleaned_data_for_step("1")['choice']

            choice = Choice.objects.filter(question__text__exact=option)


            ## Pass the data when initing the form, which is the POST
            ## data if the got_form function called during a post
            ## or the self.storage.get_step_data(form_key) if the form wizard
            ## is validating this form again in the render_done methodform 
            form = SomeForm(choice=choice, data=data) 

        return form

def get_template_names(self):
    return [TEMPLATES[self.steps.current]]

def done(self, form_list, **kargs):
    return render_to_response('done.html')

否则,当提交表单时,它只会让我回到第一个表单。有关完整说明,请参阅here。不过我使用的是 django 1.8。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    相关资源
    最近更新 更多