Flask

파이선 WTForms 라이브러리를 사용한 Flask 웹 사용자 입력 처리

coding art 2020. 5. 10. 19:30
728x90

파이선에서 microframe으로 알려진 Flask Workframe을 사용하여 웹에서 사용자 명과 비밀번호를 처리하기 위한 코드를 작성하려면 몇 가지 필수적인 스텝이 필요하게 된다.

웹에서 사용자 명과 비밀번호를 입력 받기 위해서는 HTML 태그 명령 중에서 <form> <input>을 사용하여 텍스트 정보를 처리해야 한다. 특히 <form> 사용에 관해서는 속성 정보가 정확하게 처리될 경우에 한해서 유효함 확인과 아울러 제출(submit) 승인이 가능하다.

한편 파이선에서 HTML 파일과 통신하기 위한 인터페이스 엔진이 필요한데 바로 그것이 Jinja2 templating engine 이다. HTML과 혼용하여 사용하는 Jinja2 의 사용문법은 별도로 배워야 하지만 몇 가지 중요한 점만 체크해 보자. Jinja2 코드를 구성하는 블록(block){%∙∙∙%} 형으로 기술되며 HTML 태그처럼 시작 부분이 있으면 반드시 그에 대응한 마치는 부분이 있어야 한다. 아울러 파이선과 주고받아야 할 변수는 {{변수}} 형으로 HTML 코드 속에 표현한다.아래의 예제 코드에서 {% macro∙∙∙ %}는 계속 되풀이하여 사용됨을 뜻하며 반드시 {% endmacro %}로 마쳐야 한다. macro HTML코드인 first_app.html 코드에서 라이브러리처럼 import 한 후에 macro 명인 render_field(field)를 불러 쓸 수 있다.

 

 

사용자 이름을 웹에서 <form>태그를 사용하여 입력 받기 위한 파이선 Flask 예제 app.py 코드를 살펴보기로 하자. 처번째 필요한 라이브러리로서 Flask, render_template request 이다. request @app.route(‘/’)request.form에서 사용되며 ∙∙∙.form first_app.html 코드 내부의 태그 <form>∙∙∙</form>와 대응이 이루어진다.

 

 

 

한편 라이브러리 WTforms는 파이선 언어로 웨을 개발 할 경우에 유연하게 form의 유효성 처리와 렌더링을 지원하며, Form, TextAreaField, validators가 중요한 항목들이다.

HTML 자체로 웹에서 태그 <form>을 사용하여 입력 작업 후 validation 하게끔 되어 있으나 이 결과를 HTML과는 전혀 다른 언어인 파이선 클라스 코드에서 Jinja2 templating engine을 통해서 받으려면 WTForms 라이브러리 지원을 받을 필요가 있다. Form 은 태그 <form>, TextAreaField는 태그 <TextArea>, validators도 태그 <form>과 깊은 관련을 맺고 있다.

app.py를 실행해 보면 클라스 sayhello 실행에 따른 웹에서 반응을 보면 <textarea>임을 쉽게 알 수 있다.

 

 

@app.route(‘/’)의 웹 url local:5000에서 <textarea> 압력이 완료되면 Say Hello 버튼을 클릭하여 제출(submit)하게되며 @app.route(‘/hello’) 루틴으로 웹 url local:5000/hello로 변경된다. 여기까지가 파이선 Flask Workfram을 이용하여 웹 주소 local:500에서부터 사용자 입력 데이터를 처리해 나가는 과정에 해당한다. 아울러 사용자 수가 1명 이상이라면 2명에서부터 수백명에 이르기까지 입력 데이터를 관리하려면 데이터베이스 라이브러리를 연동할 필요가 있으며 파이선에서는 sqlite3 이 지원된다.

 

 

 

폴더 구조를 살펴보기로 하자. 파이선 실행 코드인 app.py 와 함께 static 폴더와 templates 폴더가 있음을 알 수 있다. static 폴더에는 style.css HTML 코드가 들어 있는데 templates 폴더의 first_app.htmlstyle.css를 활용하려면 정확한 경로와 href 정보를 지정하여야 한다.

 

 

#app.py


from wtforms import Form, TextAreaField, validators

app = Flask(__name__)

class HelloForm(Form):
    sayhello = TextAreaField('', [validators.DataRequired()])

@app.route('/')
def index():
    form = HelloForm(request.form)
    return render_template('first_app.html', form=form)


@app.route('/hello', methods=['POST'])
def hello():
    form = HelloForm(request.form)
    if request.method == 'POST' and form.validate():
        name = request.form['sayhello']
        return render_template('hello.html', name=name)
    #return render_template('first_app.html', form=form)
    return render_template('first_app.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0')

 

static/

<!-style.css->

body {
 font-size: 3em;
}

 

templates/

<!-_formhelpers.html->

{% endmacro %}
  <dt>{{ field.label }}
  <dd>{{ field(**kwargs)|safe }}
  {% if field.errors %}
    <ul class=errors>
    {% for error in field.errors %}
      <li>{{ error }}</li>
    {% endfor %}
    </ul>
  {% endif %}
  </dd>
  </dt>
{% endmacro %}

 

<!-first_app.html->

</html>
<html>
  <head>
    <title>First app</title>
 <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
  </head>
  <body>

{% from "_formhelpers.html" import render_field %}

<div>What's your name?</div>

<form method=post action="/hello">

  <dl>
   {{ render_field(form.sayhello) }}
  </dl>

  <input type=submit value='Say Hello' name='submit_btn'>

</form>

  </body>
</html>

 

 

<!-hello.html->

<!doctype html>
<html>
  <head>
    <title>First app</title>
 <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
  </head>
  <body>

<div>Hello {{ name }}</div>

  </body>
</html>