在验证表上始终输出 "December" 月份:webapp2 和 Google App Engine (Windows 7)

On Verification Form Always Outputs "December" For Month: webapp2 and Google App Engine (Windows 7)

参加 Udacity 后端课程介绍并学习基本的 webapp2。编程相对较新,所以我会尽量说清楚。使用 64 位 Windows 7 Professional,如果重要的话。

需要注意一件事 - 我主要使用 Python 3.6 (Anaconda),但在虚拟环境中使用 运行 2.7。我对 Python 2 不太满意,这是我第一次使用 virtualenv。

我有一个 helloworld.py 文件,其中包含一个名为 MainPage 的 class,它继承自 webapp2.RequestHandler,并且包含 get 和 post 的函数定义。该文件有一个 HTML 表单,要求用户在三个单独的字段中输入他们的生日月、日和年。还有一个提交按钮。

当用户输入他们的信息时,日、月、年的有效性应该由一个单独的函数来验证(这三个都在一个名为 verify_date 的单独模块中)。每个函数基本上检查信息是否有意义(没有废话或超出范围的日期)。我知道它不会强制执行不同的月份长度(例如 2 月只有 28 天),但我并不关心这一点。

1) 如果用户输入的信息有效(例如,'January'、“1”和“2000”),页面应接受该信息并加载一条消息,内容为 "Thanks for the Validation!" 这行得通。

2) 如果三项信息中有任何一项无效,则应重新加载表单,以便用户可以重新输入所有内容。这就是问题所在。如果我为日或年输入超出范围的数字,这将起作用。但是,如果我在 "month" 字段中输入一个虚构的词,它 A) 无论如何都会加载验证语句,并且 B) 将 "December" 写入网页(我添加了一个测试语句),无论什么实际输入。例如,我可以在框中输入 "April",它仍然会打印 "December." What's going on here?

注意:我在另一个IDE 运行 Python 3.6 中独立测试了day/month/year 验证功能,它们运行良好。

# helloworld.py

import webapp2
import verify_date

form = """
<form method="post">
    What is your birthday? 
    <br>

    <label>Month
        <input type="text" name ="month">
    </label>

    <label>Day
        <input type="text" name ="day">
    </label>

    <label>Year
        <input type="text" name ="year">
    </label>

    <br>
    <br>
    <input type="submit">
</form>

""" 

class MainPage(webapp2.RequestHandler):
    def get(self):
        #self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write(form)

    def post(self):

        user_month = verify_date.valid_month(self.request.get('month'))
        user_day = verify_date.valid_day(self.request.get('day'))
        user_year = verify_date.valid_year(self.request.get('year'))


        # Test: always prints what was actually entered in the field, 
        # as expected, even if it's gibberish
        self.response.out.write(self.request.get('month'))

        # Should return the month entered (capitalized by verify_date.valid_day)
        # Prints December, regardless of what's entered 
        self.response.out.write(user_month)

        # As expected, prints the entered day if in range. Reloads form otherwise
        self.response.out.write(user_day)

        # As expected, prints the entered day if in range. Reloads form otherwise
        self.response.out.write(user_year)

        if not(user_month and user_year and user_day):
            self.response.out.write(form)
        else:
            self.response.out.write("Thanks for the validation!")

        # Test: prints the entered month, even if gibberish
        self.response.out.write(self.request.get('month'))

app = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)

# verify_date.py

def valid_month(month):
    months = ['January','February','March','April','May','June','July','August','September','October','November','December']
    months = [month.lower() for month in months]
    month = month.lower()

    if month in months:
        month = month[0].upper() + month[1::]
    else:
        print 'Sorry, that is a not a valid month.'
        month = None
    return month

def valid_day(day):
    if day.isdigit() and int(day) < 32 and int(day) > 0:
        day = int(day)
    else:
        day = None
    return day

def valid_year(year):
    if year.isdigit() and int(year) < 2021 and int(year) > 1899:
        year = int(year)
    else:
        year = None
    return year

您在使用 python 2.x 吗?我认为您的问题与以下问题有关:

在 python 2 中,列表理解中的 month 变量会覆盖传递给函数的 month arg。因此,在执行以下行后,month 保留 months 列表中最后一项的值,即 December:

months = [month.lower() for month in months]

您可以在那里使用不同的变量名以避免冲突:

months = [m.lower() for m in months]