在 Django 中,有一个视图函数需要根据某些条件来决定使用哪种表单。
有两个表单如下:
class OpenExtraForm(forms.ModelForm):
class Meta:
model = Extra
def __init__(self, *args, **kwargs):
super(OpenExtraForm, self).__init__(*args, **kwargs)
self.fields['opening_challenge'].label = "lame translation"
def clean_opening_challenge(self):
challenge = self.cleaned_data['opening_challenge']
if challenge is None:
raise forms.ValidationError('Укажите шаг, открывающий данную доп. возможность')
return challenge
class HiddenExtraForm(forms.ModelForm):
class Meta:
model = Extra
exclude = ('opening_challenge')
def __init__(self, *args, **kwargs):
super(HiddenExtraForm, self).__init__(*args, **kwargs)
视图代码如下:
@login_required
def manage_extra(request, extra_id=None, hidden=False):
if not_admin(request.user):
raise Http404
if extra_id is None:
# Adding a new extra
extra = Extra()
if hidden:
FormClass = HiddenExtraForm
else:
FormClass = OpenExtraForm
else:
# Editing an extra
extra = get_object_or_404(Extra, pk=extra_id)
if extra.is_hidden():
FromClass = HiddenExtraForm
else:
FormClass = OpenExtraForm
if request.POST:
form = FormClass(request.POST, instance=extra)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse(view_extra, args=[extra.id]))
else:
form = FormClass(instance=extra)
return render_to_response('form.html', { 'form' : form,
}, context_instance=RequestContext(request) )
问题是,如果 extra.is_hidden() 返回 True,语句 FromClass = HiddenExtraForm 不起作用。在其他条件下,它都可以工作得很顺利,即会实例化正确的表单类,并执行所有操作。但是,如果 extra.is_hidden(),调试器会显示条件已通过,它会转到下一行,什么也不做!结果,我收到一个 UnboundLocalVar 错误,指出 FormClass 根本没有被赋值。
2、解决方案
在问题中的代码中,需要确定使用 FromClass
还是 FormClass
。除了以下语句外,其他地方都使用 FormClass
:
if extra.is_hidden():
FromClass = HiddenExtraForm
因此,将 FromClass
替换为 FormClass
即可解决问题。
修改后的代码如下:
@login_required
def manage_extra(request, extra_id=None, hidden=False):
if not_admin(request.user):
raise Http404
if extra_id is None:
# Adding a new extra
extra = Extra()
if hidden:
FormClass = HiddenExtraForm
else:
FormClass = OpenExtraForm
else:
# Editing an extra
extra = get_object_or_404(Extra, pk=extra_id)
if extra.is_hidden():
FormClass = HiddenExtraForm
else:
FormClass = OpenExtraForm
if request.POST:
form = FormClass(request.POST, instance=extra)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse(view_extra, args=[extra.id]))
else:
form = FormClass(instance=extra)
return render_to_response('form.html', { 'form' : form,