0

I have been having trouble with my post function. My application is design for people to enter their birthday and if they put in a month, day, and year in right it is post to say "Thanks! That's a totally valid day" if it is not a date it is post to say "That doesn't look valid to me, friend", but it does not do that it just refreshes it self each time I push submit. Where in my code did I go wrong with my post function or is it my get and post function?

import webapp2

form="""  
<form method="post">
    What is your birthday?
    <br>
    <label>Month<input type="type" name="month"></label>
    <label>Day<input type="type" name="day"></label>
    <label>Year<input type="type" name="year"></label>
    <div style="color: red">%(error)s</div>
    <br>
    <br>
    <input type="submit">
</form> 
"""

class MainPage(webapp2.RequestHandler):

    def write_form(self, error=""):
        self.response.out.write(form % {"error": error})

    def get(self):
        self.write_form()

    def valid_year(year):
        if year and year.isdigit():
            year = int(year)
            if year > 1900 and year < 2020:
                return year

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

    months = ['Janurary',
          'February',
          'March',
          'April',
          'May',
          'June',
          'July',
          'August',
          'September',
          'October',
          'November',
          'December']


    month_abbvs = dict((m[:3].lower(),m) for m in months)

    def valid_month(month):
        if month:
            short_month =  month[:3].lower()
            return month_abbvs.get(short_month)




    def post(self):
        user_month = valid_month(self.request.get('month'))
        user_day = valid_day(self.request.get('day'))
        user_year = valid_year(self.request.get('year'))
        if not (user_month and user_day and user_year):
            self.write_form("That doesn't look valid to me, friend.")
        else:
            self.response.out.write("Thanks! That's a totally valid day!")

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

I even download python IDLE and use it instead of notpad++. When I push submit I got:

 Internal Server Error

The server has either erred or is incapable of performing the requested operation.

Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "C:\Users\ajper_000\Desktop\engineapp\main.py", line 66, in post
    user_month = valid_month(self.request.get('month'))
NameError: global name 'valid_month' is not defined
2
  • How is your form linked to your requesthandler? I.e. how does the input button know what request to make? Commented Jul 23, 2015 at 19:41
  • I think it might be better to just leave the original code instead of editing it as you fix problems. Otherwise new readers will have trouble understanding the original question. You could append edits towards the end of the question instead. Commented Jul 24, 2015 at 13:35

6 Answers 6

2

Try to replace

<form>

with

<form method="POST">

Forms, by default, use GET requests, while your request handler expects a POST request.

EDIT: It appears you have multiple problems:

  1. The original problem, to which the above is the anwser.
  2. Your indentation was wrong, causing the post method to be undefined (or defined within the get method maybe)
  3. The valid_* methods are undefined - you need to define them.
Sign up to request clarification or add additional context in comments.

3 Comments

I did and I got 405 Method Not Allowed The method POST is not allowed for this resource.
Weird. One of the related issues got this problem when the indentation was wrong. Maybe time to double-check spelling and indentation? stackoverflow.com/questions/10354425/…
Well, that means you did have indentation problems. Now you are hitting the next error, which is that you haven't defined the valid_... functions that you call
1

You should return true in the functions of valid_month, valid_year, and valid_day. Just like this code

import webapp2

months = ['Janurary',
          'February',
          'March',
          'April',
          'May',
          'June',
          'July',
          'August',
          'September',
          'October',
          'November',
          'December']


month_abbvs = dict((m[:3].lower(), m) for m in months)


def valid_month(user_month):
    if user_month:
        short_month = user_month[:3].lower()
        return month_abbvs.get(short_month)
    return True


def valid_day(user_day):
    if user_day and user_day.isdigit():
        user_day = int(user_day)
        if user_day > 0 and user_day <= 31:
            return user_day
    return True


def valid_year(user_year):
    if user_year and user_year.isdigit():
        user_year = int(user_year)
        if user_year > 1900 and user_year < 2020:
            return user_year
    return True

form = """
<form method='POST'>
 <h1>What is your birthday?</h1>
 <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>

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


class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write(form)

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

        if not (user_year and user_month and user_day):
            self.response.out.write(form)
            self.response.out.write("Please enter valid a function")
        else:
            self.response.out.write('tThanks for that')

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

Because when the function valid_month is called it should return True to display the error message in browser.

2 Comments

So Raja - you are saying that, if user_month: results in a false, we should return True? All of your validations will never return false. Terrible advice. Downvote from me.
We should return to access data in other
0

The cause of the 405 is right at the bottom of the stack trace.

NameError: global name 'valid_month' is not defined

suggests that you don't have a function named valid_month. If you don't, then write one. If you do, then post it.

3 Comments

I just add the code and i still get NameError: global name 'valid_month' is not defined
You added valid_day and valid_year. I don't see a valid_month. Add that.
I did add valid_month. Its right under all the months.
0

Alexander, I am doing the same course at udacity and I hit the same problem. But before going to the stage where you added the functions to check the user input I just checked the output in the browser right after the teacher changed the code afte the combo box. I had the same problem of getting "405 Method Not Allowed" along with the message on the next line "The method POST is not allowed for this resource. I scanned the code and compared it line by line and word by word and character by character with that code in the video "https://www.udacity.com/course/viewer#!/c-cs253/l-48736183/m-48714317" but it did not help.

Then I hit the accompanying wiki for the course and copied exactly the 4 lines that I doubted has the problem. And suddenly it worked. I used different on line text comaprison tools to find out what was the difference but could not figure out what was the problem. I copy and paste here both the versions below:

Version 1: The verison that did not work and gave the 405 error:

def get(self):
    self.response.out.write(form)

def post(self):
    self.response.out.write("Thanks! that's a totally valid day!")

Version 2: The version that works:

def get(self):
    self.response.out.write(form)

def post(self):
    self.response.out.write("Thanks! That's a totally valid day!")

I can't see the differenece between these two pieces of code but even then version 1 gives error but version 2 gives the desired output. Although I have exactly copied and pasted the two versions ( given above) of the code from Notepade++ I still took screenshots so that the readers do not say that I might have made some indentation problem. Here are the screenshots of the two versions: Version 1: That did not work: enter image description here

Verson 2: That works:

enter image description here

Although the problem is solved at the moment but I wonder what is causing the problem! Any python guru can explain why?

Comments

0

Declaring the methods outside the class and before the class declaration and after the end of the form works for me.The code was like this.

import webapp2

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>

 <input type="submit">
</form>
"""
months = ['January',
                 'February',
                 'March',
                 'April',
                 'May',
                 'June',
                 'July',
                 'August',
                 'September',
                 'October',
                 'November',
                 'December']

month_abbvs = dict((m[:3].lower(),m) for m in months)

def valid_month(month):
           if month:
              shortMonth=month[:3].lower()
              return month_abbvs.get(shortMonth)

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

def valid_year(year):
         if year and year.isdigit():
            year=int(year)
            if year >=1900 and year <=2020:
             return year
class MainHandler(webapp2.RequestHandler):


    def get(self):
       # self.response.headers['Content-Type']='Text/HTML'
        self.response.write(form)

    def post(self):
        user_moth = valid_month(self.request.get('month')) 
        user_day = valid_day(self.request.get('day'))
        user_year = valid_year(self.request.get('year'))  
        #self.response.out.write("Thanks... ")

        if not (user_year and user_moth and user_day):
            self.response.out.write(form)
        else:
            self.response.out.write('tThanks for that')



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

Hope it will help.Otherwise you can pass additional parameter self to these function definition and call it using instance variable

2 Comments

Why would you declare these outside the class? Seems to me they belong to that class.
Actually it was a problem from udacity learning python tutorial. So as a learner I found it worked and I could connect to Google app engine. That's all. There is chance where I can be wrong, but I was following the tutorial.
0

Python doesn't scope code to the local class automatically; you need to tell it to.

valid_month = self.valid_month(self.request.get('month')) 

The next error you will thus encounter will be

TypeError: valid_month() takes exactly 1 argument (2 given)

You will need to declare 'self' as the first parameter of 'valid_month' method.

def valid_month(self, month):

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.