2021년 12월 4일 토요일

python에서 flask 로 web app 그리고 ajax calc jQuery 예제 맛보기


https://swlock.blogspot.com/2021/11/python-web-applications-with-flask.html

앞에서 flask를 이용해서 간단하게 웹앱을 제작해 보았습니다. 계산 결과를 받아서 전체 화면 페이지가 갱신이 되는 구조입니다. 그러나 어디까지나 간단한 예제일뿐 우리가 봐오던 웹앱과는 거리가 멀어 보입니다. 

단순 HTML의 한계를 뛰어 넘어야 하는데, Ajax라고 불리는 기술이 필요합니다. 처음 접했을때 뭔가 거창하게 들립니다만 Ajax는 자바스크립트에 기반하는 부분 데이터를 주고 받고 그 결과를 가지고 web 컨텐츠를 조작하는 기술이라고 보면됩니다.

(Ajax란 Asynchronous JavaScript and XML의 약자입니다. Ajax는 동적인 웹 페이지를 만들기 위한 개발 기법의 하나로 웹 페이지 전체를 다시 로딩하지 않고도, 웹 페이지의 일부분만을 갱신할 수 있습니다.)

예전에는 만들려면 좀 더 복잡했었는데, JavaScript 전문가가 아니다보니, jQuery라는 라이브러리를 사용해서 좀 더 쉽게 Ajax를 이용 할 수 있습니다.


이번 시간의 목표는 이전에 했던 계산기의 전체 페이지를 갱신하지 않고 일부분만 갱신하도록 구현해보겠습니다.


Ajax, Javascript, Flask, jQuery 에 대해서 조금씩 다루어지지만 깊게 들어가지는 않기 때문에 위 내용을 잘 몰라도 이해하는것은 큰 무리가 없을것 같습니다.


Flask의 render_template

Flask는 html파일을 만들어 놓고 비슷한 페이지를 조금씩 조작해서 처리 할 수 있는데 Jinja2 template engine을 사용합니다. 알아 두어야 하는 점이 하나 있는데 

@app.route("/")

def index():

return render_template('input_form.html')

이런 형태로 코드를 구현하면 'input_form.html' 파일을 현재 폴더에서 찾는게 아니라 templates 이란 하위 폴더 구조에서 찾게 됩니다.

https://flask.palletsprojects.com/en/2.0.x/quickstart/#rendering-templates

Case 1: a module:

/application.py
/templates
    /hello.html

Case 2: a package:

/application
    /__init__.py
    /templates
        /hello.html

즉 위와 같이 폴더를 구성해야합니다.

이번에는 Jinja2 문법에 대해서는 사용하지 않고 html 파일 그대로 브라워저로 보낼 예정이라 폴더 구조 부분만 이해하면 됩니다.


jQuery

Ajax 와 동적인 html처리를 위한 javascript 라이브러리 입니다.

html 코드 위치에 아래와 같은 코드를 삽입하고

<head>

  <script src="https://code.jquery.com/jquery-3.5.0.js"></script>

</head>

자신이 작성한 script는 body의 마지막 부분에 추가합니다.

스크립트 내에 아래와 같은 코드가 있습니다.

$(선택자).동작함수();

달러($) 기호는 jQuery를 의미하고, jQuery에 접근할 수 있게 해주는 식별자입니다.

$() 함수에 전달되는 인수는 반드시 따옴표("")를 사용한 문자열 형태로 전달되어야 합니다.

아이디(id)를 사용하여 특정 HTML 요소를 선택할 수도 있습니다. (#이용)

선택자를 이용하여 원하는 HTML 요소를 선택하고, 동작 함수를 정의하여 선택된 요소에 원하는 동작을 설정합니다.

여기에서 사용한 예제는 아래 링크를 참고 하였습니다.

https://api.jquery.com/click/


Javascript 기본

var 는 변수를 정의할때 사용합니다. javascript 언어는 type은 미리 정하지 않지만 변수명은 미리 정해야합니다.


입력 page 소스

<!--https://api.jquery.com/click/-->
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>calc flask demo</title>
  <script src="https://code.jquery.com/jquery-3.5.0.js"></script>
</head>
<body>
 
<input type="text" id="txt1" name="inputdata"></input>
<button id="btn1">submit</button>

<div id="result1">
</div>

</p>

<script>
$( "#btn1" ).click(function() {
	var txt1_v = $('#txt1').val();
	var postdata = {
		'inputdata':txt1_v
	}
	<!--alert( "Handler for .click() called." );-->
	$.ajax({
		type: 'POST',
		url: '{{url_for("ajax_page")}}',
		data: JSON.stringify(postdata),
		dataType : 'JSON',
		contentType: "application/json",
		success: function(data){
			$("#result1").text("result:"+data['inputdata'] + '=' + data['rlt']);
			<!--alert('success :' + data['inputdata'] + '=' + data['rlt'])-->
		},
		error: function(request, status, error){
			alert('ajax error:['+status+']['+error+']')
		}
	})
});

</script>
 
</body>
</html>


입력 html을 브라우저로 올린 화면

브라우저로 로딩을 하면 위와 같은 화면이 나온다.


스크립트 설명

주된 핵심은 3줄이 됩니다. 

<input type="text" id="txt1" name="inputdata"></input>

<button id="btn1">submit</button>

위 두줄은 입력을 받기위한 것입니다.

<div id="result1">

</div>

div는 결과를 출력하기 위한 용도입니다. 모두 id값이 들어있음을 주목 하세요. jQurey에서 #id를 하면 쉽게 접근이 가능합니다.

$( "#btn1" ).click(function() { 여기서 부터는 버튼을 클릭했을때 처리하는 부분입니다.

txt1_v 에 값을 읽은뒤 postdata 를 이용해서 json format 을 만들게 됩니다.

$.ajax({ 를 이용해서 ajax를 사용하게 되는데 이때 url: '{{url_for("ajax_page")}}', 여기에 기록된 page로 접속을 하게 되며 비로서 Flask에서 처리하게 됩니다. 

이번에는 Flask가 처리를 하고나면 success 쪽으로 넘어오게 되는데

$("#result1").text("result:"+data['inputdata'] + '=' + data['rlt']);

핵심 코드는 위 코드입니다. 위에 div로 설정해둔 아무런 text내용도 없는 곳에 위 코드로 인해서 결과가 기록되게 됩니다. 즉 전체 페이지가 갱신되는게 아니라 web page의 일부분만 값이 변경된다는 의미입니다.

다음으로는 Flask 코드입니다.


Flask 소스

from flask import Flask
from flask import request
from flask import render_template
from flask import jsonify

app = Flask(__name__)

@app.route("/")
def index():
	return render_template('input_form.html')

@app.route("/ajax_page", methods=['POST'])
def ajax_page():
	data = request.get_json()
	print(data)
	calc_result = calc(data['inputdata'])
	rdata = {}
	rdata['inputdata']=data['inputdata']
	rdata['rlt']=calc_result
	print(rdata)
	return jsonify(rdata)

def calc(inputdata):
	return str(eval(inputdata))

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

이전보다 코드가 깔끔해졌습니다. 

위에서 작성한 html은 input_form.html 이름으로 만들어 templates 폴더 아래에 위치하도록 합니다.  

/ 로 접속하되면 계산기 입력을 받을 수 있는 페이지 input_form.html이 나오도록 해줍니다.

그리고 /ajax_page 에 json format으로 접속이 되면 inputdata 항목에 있는 내용을 계산한뒤 다시 json 형태로 전달하면 됩니다.

아래 코드가 json을 받아서 출력해보는 코드입니다.

data = request.get_json()

print(data)

아래 코드는 계산된 결과를 rdata에 담아서 json으로 리턴하는 내용입니다.

rdata = {}

rdata['inputdata']=data['inputdata']

rdata['rlt']=calc_result

print(rdata)

return jsonify(rdata)


실행화면


소스코드



댓글 없음:

댓글 쓰기