首页 > 解决方案 > Django: forms.ChoiceField, overriding forms __init__

问题描述

I am trying to implement a forms.ChoiceField() with values from a view. I already can do it if I declare the choices in the forms.py, but that's not what I need.

views.py:

def add_crime(request):
        values = [('1','um'),('2','dois'),('3','tres')]
        if request.method == 'POST':
            form = AddCrimeForm(request.POST, values)
            if form.is_valid():
                # do stuff
                return redirect('show_crime')
        else:
            form = AddCrimeForm(request.GET)
        return render(request, 'add_crime.html', {'form': form})

forms.py:

class AddCrimeForm(forms.Form):
    tests = forms.ChoiceField()
    def __init__(self, testList, args, **kwargs):
        self.testList = testList
        super(AddCrimeForm,self).__init__(*args, **kwargs)  # testList not in args!
        self.fields['tests'].widget = forms.CheckboxSelectMultiple()
        self.fields['tests'].choices = self.testList

Error:

AttributeError: 'tuple' object has no attribute 'get'

From the feedback, do I have to implement another __init__ with one argument in forms.py? That's what I would try in Java.

My final goal is to implement two ChoiceField and the second one would depend from the first one. Is there a better way?

标签: djangopython-3.xdjango-formsdjango-viewschoicefield

解决方案


这里有两个错误:第一个是在AddCrimeForm. *args__init__标题中需要一个星号 ( ) *

class AddCrimeForm(forms.Form):

    tests = forms.MultipleChoiceField()

    def __init__(self, testList, *args, **kwargs):
        self.testList = testList
        super(AddCrimeForm,self).__init__(*args, **kwargs)  # testList not in args!
        self.fields['tests'].widget = forms.CheckboxSelectMultiple()
        self.fields['tests'].choices = self.testList

如果您想选择多个选项,您可能还想制作forms一个MultipleChoiceField[Django-doc]

在您看来,您应该构造一个AddCrimeForm, 列表values作为第一个元素,因为它被定义为您的第一个元素AddCrimeForm

def add_crime(request):
        values = [('1','um'),('2','dois'),('3','tres')]
        if request.method == 'POST':
            form = AddCrimeForm(values, request.POST)
            if form.is_valid():
                # do stuff
                return redirect('show_crime')
        else:
            form = AddCrimeForm(values)
        return render(request, 'add_crime.html', {'form': form})

除非您想处理表单中的查询字符串,否则通常不会传递request.GET给表单,否则它将采用查询字符串中定义的值。


推荐阅读