问题描述:

I have the following form i populate based on a question id:

class QuestionForm(forms.Form):

options = forms.ModelMultipleChoiceField(queryset=Option.objects.none(),

widget=forms.RadioSelect)

def __init__(self, *args, **kwargs):

question_id = kwargs.pop('question_id', None)

if question_id:

print question_id

super(QuestionForm, self).__init__()

question = Question.objects.get(pk=question_id)

ts = Option.objects.filter(question = question)

for t in ts:

print t.name

self.fields['options'].queryset = Option.objects.filter(question = question)

def clean(self):

print 'in clean'

cleaned_options = self.cleaned_data['options']

try:

print cleaned_options

raise forms.ValidationError('That is not the right answer. Try again.')

except:

return cleaned_options

I call it from my view like this:

if request.method == "POST":

print 'in post'

form = QuestionForm(request.POST, question_id=question.id)

print '---'

options = request.POST.getlist('options')

option = options[0]

print option

if form.is_valid():

print '******'

My template looks simply like this:

<form action="" method="post">

{% csrf_token %}

{{ form }}

{{ form.errors }}

<br />

<button type="submit">Save</button>

</form>

I get the option I selected, but I am unable to trigger the clean method to alert the user whether the correct answer is selected or not.

What am I doing wrong?

网友答案:

You have a number of issues in your __init__ method.

The one that's causing your actual problem is that you are not passing args and kwargs on to the superclass method. So the form data is never actually assigned, so is_valid can never be true. You should be doing this:

super(QuestionForm, self).__init__(*args, **kwargs)

Just as important, though, that super call should not be indented inside the if statement. You need to make that call whatever happens. The easiest fix here would be to move it to before the if.

相关阅读:
Top