Django表单在python shell中引发KeyError,视图中没有错误

时间:2014-06-05 19:56:22

标签: python django shell exception django-forms

我有一个django形式:

class ParameterForm(forms.Form):
    pcat = forms.IntegerField()
    gpa = forms.FloatField()
    city = forms.CharField(required = False)
    state = forms.CharField(required = False, min_length = 2, max_length = 2)

当我在python shell中测试这个表单时,我能够捕获丢失的数据,如下所示:

>> parameters = {'pcat' : 70, 'gpa' : 3.5, 'state' : 'TX'}
>> form = ParameterForm(parameters)
>> try:
..     form.data['city']
.. except KeyError:
..     print "No city"
>> No city

但是,当我尝试在我的视图中使用相同的逻辑时,异常永远不会引发,并且函数会继续执行,直到缺少的数据导致它中断。

来自views.py的

def sByInfo(request):
    print "\n \n NEW CALL"

    parameter_form = ParameterForm(request.GET)

    if parameter_form.is_valid():


        ranked = Ranked.objects.all()
        unranked = Unranked.objects.all()

        ranked_matches = [] # List for ranked institution matches
        unranked_matches = [] # List for unranked institution matches

        try:
            gpa = parameter_form.data['gpa']
            gpa = float(gpa)
            print gpa
            pcat = parameter_form.data['pcat']
            pcat = int(pcat)
            print pcat

            try:
                city = parameter_form.data['city']
                print city
                state = parameter_form.data['state']
                print state

                position = getPos(city, state)
                lati = Decimal(position['lat'])
                loni = Decimal(position['lon'])

                print "\n RANKED"
                for x in ranked:
                    print x.name
                    average_gpa = (x.gpa_expected + x.gpa_overall) / 2
                    print average_gpa
                    if gpa >= average_gpa:
                        print "GPA good"
                        try: 
                            ranked_matches.index(x)
                            print "School already added"
                        except ValueError:
                            ranked_matches.append(x)
                            print "School added"
                    else:
                        print "GPA too low"

                    if pcat >= x.min_pcat:
                        try: 
                            ranked_matches.index(x)
                            print "School already added"
                        except ValueError:
                            ranked_matches.append(x)
                            print "School added"
                    else:
                        print "PCAT too low"

                    lat = Decimal(x.lat)
                    lon = Decimal(x.lon)
                    difference = posDifference(lati, loni, lat, lon)
                    print "Distance is {} miles".format(difference)

                    if difference <= 150:
                        try: 
                            ranked_matches.index(x)
                            print "School already added"
                        except ValueError:
                            ranked_matches.append(x)
                            print "School added"
                    else:
                        print "School out of range"

                print "\n UNRANKED"
                for y in unranked:
                    print y.name
                    average_gpa = (y.gpa_expected + y.gpa_overall) / 2
                    if gpa >= average_gpa:
                        try: 
                            unranked_matches.index(y)
                            print "School already added"
                        except ValueError:
                            unranked_matches.append(y)
                            print "School added"
                    else:
                        print "GPA too low"

                    if pcat >= y.min_pcat:
                        try: 
                            unranked_matches.index(y)
                            print "School already added"
                        except ValueError:
                            unranked_matches.append(y)
                            print "School added"
                    else:
                        print "PCAT too low"

                    lat = Decimal(y.lat)
                    lon = Decimal(y.lon)
                    difference = posDifference(lati, loni, lat, lon)
                    print "Distance is {} miles".format(difference)

                    if difference <= 150:
                        try: 
                            unranked_matches.index(y)
                            print "School already added"
                        except ValueError:
                            unranked_matches.append(y)
                            print "School added"
                    else:
                        print "School out of range"



            except KeyError: ## City or State was not submitted
                print "City or state missing"

                try:
                    state = request.GET['state']

                    for x in ranked:
                        average_gpa = (x.gpa_overall + x.gpa_expected) / 2
                        if gpa >= average_gpa:
                            try:
                                ranked_matches.index(x)
                                print "School already added"
                            except ValueError:
                                ranked_matches.append(x)
                                print "School added"
                        else:
                            print "GPA too low"

                        if pcat >= x.min_pcat:
                            try:
                                ranked_matches.index(x)
                                print "School already added"
                            except ValueError:
                                ranked_matches.append(x)
                                print "School added"
                        else:
                            print "PCAT too low"

                        if state.lower() == x.state.lower():
                            try:
                                ranked_matches.index(x)
                                print "School already added"
                            except ValueError:
                                ranked_matches.append(x)
                                print "School added"
                        else:
                            print "School not in state"


                    for y in unranked:
                        average_gpa = (y.gpa_expected + y.gpa_overall) / 2
                        if gpa >= average_gpa:
                            try:
                                unranked_matches.index(y)
                                print "School already added"
                            except ValueError:
                                unranked_matches.append(y)
                                print "School added"
                        else:
                            print "GPA too low"

                        if pcat >= y.min_pcat:
                            try:
                                unranked_matches.index(y)
                                print "School already added"
                            except ValueError:
                                unranked_matches.append(y)
                                print "School added"
                        else:
                            print "PCAT too low"

                        if state.lower() == y.state.lower():
                            try:
                                unranked_matches.index(y)
                                print "School already added"
                            except ValueError:
                                unranked_matches.append(y)
                                print "School added"
                        else:
                            print "School out of state"

                except KeyError:
                    print "City and state missing"

        except KeyError:
            return render('You must enter both GPA & PCAT scores')
    else:
        return render_to_response('index.html', {'error' : 'PCAT and GPA values are required.', 'form' : parameter_form})

    return render_to_response('results.html', {'ranked_matches' : ranked_matches, 'unranked_matches' : unranked_matches}, context_instance = RequestContext(request))

我很难过为什么这个异常会引发shell而不是我的视图?感谢所有帮助。

3 个答案:

答案 0 :(得分:0)

正如shavenwarthog所说,城市似乎是一个空字符串,这就是为什么不提出异常的原因。

如果你想在城市为空时引发错误,你可以:

  • 删除表单属性中的required=False(但我想这不是您想要的)
  • 使用:if not form.data['city'] # returns False if string is empty
  • 测试字符串是否为空

答案 1 :(得分:0)

我能够解决这个问题如下:

if len(parameter_form.data['city']) != 0:

检查string的长度是否为0。

答案 2 :(得分:0)

我没有让Django安装ATM,所以我无法尝试我的假设,但您必须致电form.is_valid()填写.data属性:

>>> parameters = {'pcat' : 70, 'gpa' : 3.5, 'state' : 'TX'}
>>> form = ParameterForm(parameters)
>>> form.is_valid()
>>> form.data['city']
''