Django: forms.ChoiceField, переопределение форм __init__

Я пытаюсь реализовать form.ChoiceField() со значениями из представления. Я уже могу это сделать, если объявлю варианты в form.py, но это не то, что мне нужно.

просмотров.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})

формы.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

Ошибка:

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

Судя по отзывам, нужно ли мне реализовать еще один __init__ с одним аргументом в forms.py? Это то, что я бы попробовал на Java.

Моя конечная цель - реализовать два ChoiceField, а второй будет зависеть от первого. Есть ли способ лучше?


person user851072    schedule 07.11.2018    source источник
comment
Здесь первым параметром вашего AddCrimeForm должен быть values. Вы также забыли добавить звездочки для *args.   -  person Willem Van Onsem    schedule 07.11.2018


Ответы (1)


Здесь две ошибки: первая в 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 в форму, поскольку в противном случае она будет принимать значения, определенные в строке запроса.

person Willem Van Onsem    schedule 07.11.2018