有多种可能性时处理Django表单?

时间:2016-08-22 14:14:01

标签: django django-forms django-views

如果您在进入视图时不知道要使用哪种表单,那么在视图中处理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处理这种情况的方法是什么?

感谢。

1 个答案:

答案 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})

这样,您可以扩展其他国家/地区的代码,而不必更改代码。