인프런 커뮤니티 질문&답변

연규양님의 프로필 이미지
연규양

작성한 질문수

파이썬 플라스크(Flask) 기반 웹 개발 및 업무 자동화 서비스 활용

파일 업로드 기능 만들기

구구단 문제풀이 질문

작성

·

248

0

구구단 출력 문제인데 질문이 있습니다.

main.py

from flask import Flask
from flask import render_template
from flask import redirect
from flask import request
from flask import url_for

app = Flask(__name__)

@app.route("/")
@app.route("/<int:num>", methods=['POST', 'GET'])
def gugudan(num=None):
    if request.method == 'GET':
        return render_template('index.html', gugudan=None)
    else:
        temp = request.form['input']
        return render_template('index.html', gugudan=temp)

if __name__ == "__main__":
    app.run(debug=True)

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='file.css') }}">
</head>
<body>
    <form action="/" method="POST">
        <p><input type="text"/ id="input" value="name"><input type="submit"></button></p>
    <form>

    {% if gugudan == None%}
        <p>Have to Type number</p>
    {% else %}
        <p>숫자가 입력되었습니다</p>
    {% endif %}
</body>
</html>

 

위와 같이 main.py에서 method 타입을 2가지로 나눠서 한번에 처리도 가능할거라 생각했는데, method not allowed가 나오네요.
혹시 무엇이 문제일까요?

 

답변 1

0

  1. html 파일에 오탈자 수정이 필요합니다.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="{{ url_for('static', filename='file.css') }}">
    </head>
    <body>
        <form action="/" method="POST">
            <p>
                <input type="text" id="input" value="name">
                <input type="submit"/>
            </p>
        </form>
    
        {% if gugudan == None%}
            <p>Have to Type number</p>
        {% else %}
            <p>숫자가 입력되었습니다</p>
        {% endif %}
    </body>
    </html>
  2. form 태그의 action을 보면 "/" 라고 입력되어있고, app.py에서 "/"는 메서드 방식이 지정되어 있지 않습니다. 임시로 post와 get 모두 받을 수 있게 지정해주겠습니다.

@app.route("/", methods=['POST', 'GET'])
@app.route("/<int:num>", methods=['POST', 'GET'])
def gugudan(num=None):
    if request.method == 'GET':
        return render_template('index.html', gugudan=None)
    else:
        temp = request.form['input']
        return render_template('index.html', gugudan=temp)

 

이렇게 코드를 수정하시고 실행시켜보시면 더 이상 method not allowed 에러가 나타나지 않을 겁니다.

그러나 Bad Request 에러가 나타나는데 이는 숫자를 넣을 input에 name이 할당되지 않은 채로 request.form을 사용해서 그렇습니다. name을 할당시켜줍니다.

그리고 기존에 name으로 줬던 value 값을 서버에서 받아오는 gugudan 값으로 바꾸고 아래에서 결과를 보기 쉽게 p태그 안에 나타나도록 코드를 추가합니다. (추가한 p 태그 부분은 이해하기 편하도록 넣은 코드이며, 제외해도 괜찮습니다.)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='file.css') }}">
</head>
<body>
    <form action="/" method="POST">
        <p>
            <input type="text" id="input" name="input" placeholder="숫자를 입력하세요." value="{{ gugudan }}">
            <input type="submit"/>
        </p>
    </form>
    <p>gugudan = {{ gugudan }}</p>
    {% if gugudan == None %}
        <p>Have to Type numberc
    {% else %}
        <p>숫자가 입력되었습니다</p>
    {% endif %}
</body>
</html>

 

이제 실행해보면 다음과 같이 나타납니다.

첫화면

image

숫자 제출

image

 참고로 작성하신 코드에서는 버튼 클릭을 통해 "/<int:num>" 부분이 호출될 일은 절대 없습니다. (action이 /, 방식이 post이기 때문)

대신 인터넷 주소창에 /아무숫자입력 하고 이동을하면 숫자를 입력했다고 결과는 나올테지만, 실제로는 None 값이 찍히게 될텐데, 이는 get 방식이며, if문을 통해 get 방식일 경우 gugudan은 None으로 값을 주셨기 때문입니다.

====================================================

추가 내용으로, 위 코드는 숫자가 아닌 문자나 빈 값을 입력해도 숫자를 입력했다고 나타납니다.

imageimage

온전히 숫자만 받기를 원한다면, input type을 number로 바꿔 문자 입력 자체를 차단하거나,

javascript를 이용해 숫자 이외의 문자나 빈 값이 들어오면 서버로 보내지 않고 경고 메세지를 띄우거나,

아니면 아예 서버 단에서 숫자인지 확인하고 아니라면 잘못된 숫자를 입력했다는 페이지로 안내하면 원래 의도대로 적용할 수 있겠습니다.

 

연규양님의 프로필 이미지
연규양

작성한 질문수

질문하기