如果您在进入视图时不知道要使用哪种表单,那么在视图中处理Django表单的正确方法是什么?我有一个视图,它根据会话变量确定要呈现的表单类型:
# views.py
def enter_location(request):
country = request.session['country']
if request.method == "POST":
if country == 'US':
form = USLocationForm(request.POST)
elif country == 'GB':
form = GBLocationForm(request.POST)
elif country == 'CA':
form = CALocationForm(request.POST)
else:
form = OtherLocationForm(request.POST)
if form.is_valid():
# do stuff...
pass
else:
if country == 'US':
form = USLocationForm(initial={'country': country})
elif country == 'GB':
form = GBLocationForm(initial={'country': country})
elif country == 'CA':
form = CALocationForm(initial={'country': country})
else:
form = OtherLocationForm(initial={'country': country})
context = {'form': form}
return render(request, template, context)
显然,这是一个丑陋的代码,它不会随着我添加更多国家而扩展。我试图通过辅助函数确定表单类型来缩短我的观点:
# views.py
from location.forms import LocationForm
def enter_location(request):
country = request.session['country']
if request.method == "POST":
form = LocationForm.get_form(country)
submitted_form = form(request.POST)
if submitted_form.is_valid():
# do stuff...
pass
else:
form = LocationForm.get_form(country)
context = {'form': form}
return render(request, template, context)
# location/forms.py
class LocationForm(forms.Form):
country = forms.ChoiceField(choices = choices.COUNTRIES_AND_EMPTY,)
city = forms.CharField()
email = forms.EmailField()
@staticmethod
def get_form(country):
if country == 'US':
return form = USLocationForm(initial={'country': country})
elif country == 'GB':
return form = GBLocationForm(initial={'country': country})
elif country == 'CA':
return form = CALocationForm(initial={'country': country})
else:
return form = OtherLocationForm(initial={'country': country})
问题是,当视图运行时,我会得到" TypeError"' USLocationForm'对象不可调用""在这一行:
submitted_form = form(request.POST)
当国家/地区是' GB'或者' CA'并选择了适当的表格。我运行调试器并做了#34;键入(表单)"在任何一种情况下,使用两个视图和表单属性看起来都是相同的。当你第一次在GET块中实例化表单而不是在POST期间再次实例化它然后用发布的数据填充它时,是否会发生一些不同的事情?当可以选择多种可能形式中的一种时,Django处理这种情况的方法是什么?
感谢。
答案 0 :(得分:1)
没有“正确的方法”来处理这个问题,但你可以做的一件事就是使用映射。
示例:
form_mappings = {
'US': USLocationForm,
'GB': GBLocationForm,
#...
}
def enter_location(request):
country = request.session['country']
country_form = form_mappings.get(country, OtherLocationForm)
if request.method == "POST":
form = country_form(request.POST)
#...
else:
form = country_form(initial={'country': country})
这样,您可以扩展其他国家/地区的代码,而不必更改代码。