python-flask / 4. flask와 SQLite 연동 - 입력값 db로 입력하기

dothouse·2024년 1월 28일

python_flask

목록 보기
5/11

0. select2 페이지 구현하기 위한 선택 값 처리하기

select1 에서 선택된 사용자들의 선호가 sql 데이터의 한 형태로 저장되게 하기


git : https://github.com/dothouse/project1/blob/master/web
Tool : python / python-flask / html /javascript / css

✅사용 파일

D:\song\practice\project1\web\jeju\views\select2.py
https://github.com/dothouse/project1/blob/master/web/jeju/views/select2_views.py

D:\song\practice\project1\web\jeju\model.py
https://github.com/dothouse/project1/blob/master/web/jeju/models.py

D:\song\practice\project1\web\jeju\__init__.py
https://github.com/dothouse/project1/blob/master/web/jeju/__init__.py

D:\song\practice\project1\web\jeju\templates\select\select2.html
https://github.com/dothouse/project1/blob/master/web/jeju/templates/select/select2.html


1. select2 페이지 구성을 위한 틀 잡기

http://127.0.0.1:5000/select/select1에서 form, submit으로 전송된 데이터를 확인하기 위해 http://127.0.0.1:5000/select/select2에서 빈페이지를 완성하고, 데이터가 어떤 형태로 넘어오는지 확인하자.

✅ 새로운 페이지를 구성하기 위해는 3단계를 거처야 한다.

    1. 구현하고자 하는 페이지(html) 만들기
    1. 해당 페이지를 구동하기 위한 views 파일 만들기
    1. __init__.py에 blueprint 기능 추가

-> 항상 이 순서를 기억
-> 이 순서에 따라 틀을 먼저 만들고, html파일과 views파일을 수정하는 것이 확인을 위해 편하다.

1) select2.html 파일 만들기

[파일명]D:\song\practice\project1\web\jeju\templates\select\select2.html

{% extends 'base.html' %}
{% block content %}
<body>
<div class="container my-3">
	<h1>select2 테스트</h1>
</div>
</body>
{% endblock %}

✅ 'select2 테스트'라는 문장만 나타나는 페이지 완성

2) select2_views.py 파일 만들기

[파일명]D:\song\practice\project1\web\jeju\views\select2.py

from flask import Blueprint, url_for
from werkzeug.utils import redirect

bp = Blueprint('select2', __name__, url_prefix='/select')

@bp.route('/select2', methods=('GET', 'POST'))
def show_select2():
    return render_template("select/select2.html")

✅ select2.html의 연결 기능만을 포함한 새로운 views 파일을 만들기

  • 새로운 views 파일을 만들때 blueprint 기능을 사용하기 때문에 __init__.py에 새로운 blueprint를 추가해야 한다.

3) __init__.py 파일 수정하기

D:\song\practice\project1\web\jeju\__init__.pyselect2 blueprint 추가하기

from flask import Flask

# app 구동
def create_app():
    app = Flask(__name__)
      
    ### blueprint - select2추가_views
    from .views import main_views, select1_views, select2_views
    
    app.register_blueprint(main_views.bp)
    app.register_blueprint(select1_views.bp)
    app.register_blueprint(select2_views.bp) - select2 추가시 추가
    
    return app

✅ 새롭게 추가된 select2_views 파일을 불러오고, app.register_blueprint를 통해 등록해줘야 한다.

2. 전송된 데이터 확인하기

1) flask run을 구동해 첫페이지에서 제출버튼을 클릭하기 전에 크롬의 개발자 환경(f12)을 켜둔다.
2) 개발자 환경에서 network 메뉴를 선택한 뒤에 제출 버튼 클릭

3) 새로운 페이지에 넘어갔을때 select2를 선택
4) select2 페이지에서 넘어오는 데이터 확인

✅ 질문지의 name 과 선택한 값option이 전송된다.

dropdown ->month: monthType1
checkbox -> bank : add_police

✅ 질문을 선택하지 않을 경우 데이터가 넘어오지 않는다.

✅ 넘어오는 데이터를 조회하는 방법

`request.form['name']

3. 전송된 데이터 처리하기

전송된 데이터를 파이썬 코드로 정제하고, sql 데이터 형태로 저장하기


from flask import Blueprint, render_template, request, url_for, redirect
from werkzeug.utils import redirect

from jeju import db
from jeju.models import selectData

bp = Blueprint('select2', __name__, url_prefix='/select')


@bp.route('/select2', methods=('GET', 'POST'))
def show_select2():
    # selectd query에 데이터 삽입

    # alert의 history.back()이 안되는 경우 회피하는 1번째 방법
    try:
        request.form['spot2']
    except:
        return redirect('/select1')

   # 관광지 대분류
    if request.form['spot1'] == 'spot1Type1':
        spot1Type_str = '경관, 포토, 스팟'
        spot1Type = 1
    elif request.form['spot1'] == 'spot1Type2':
        spot1Type_str = '반려동물, 동반, 애견'
        spot1Type = 2
    elif request.form['spot1'] == 'spot1Type3':
        spot1Type_str = '체험, 레저'
        spot1Type = 3
    elif request.form['spot1'] == 'spot1Type4':
        spot1Type_str = '도보, 등산, 오름, 숲길'
        spot1Type = 4
    elif request.form['spot1'] == 'spot1Type5':
        spot1Type_str = '테마, 실내, 박물관, 미술, 유적지, 역사'
        spot1Type = 5
    # alert의 history.back()이 안되는 경우 회피하는 2번째 방법
    elif request.form['spot1'] == '':
        return redirect(url_for('select1.open_select1'))

### 중략 
### ...

    # 숙소 추가 옵션
    pension_opt_list = ['pool', 'garden', 'sea', 'nocost', 'bus']
    for pension_opt in pension_opt_list:
        try:
            request.form[pension_opt]
            globals()[str(pension_opt)] = 1
            globals()[str(pension_opt) + '_str'] = '선택'
        except:
            globals()[str(pension_opt)] = 0
            globals()[str(pension_opt) + '_str'] = '미선택'

    # 주변 추가 옵션
    add_opt_list = ['police', 'hospital', 'bank', 'mart', 'gift']
    for add_opt in add_opt_list:
        try:
            request.form[add_opt]
            globals()[str(add_opt)] = 1
            globals()[str(add_opt) + '_str'] = '선택'
        except:
            globals()[str(add_opt)] = 0
            globals()[str(add_opt) + '_str'] = '미선택'

    # data 추가
    new_data = selectData(month=monthType, month_str=monthType_str,
                          spot1=spot1Type, spot1_str=spot1Type_str,
                          spot2=spot2Type, spot2_str=spot2Type_str,
                          food=foodType, food_str=foodType_str,
                          pet=petType, pet_str=petType_str,
                          pool=pool, garden=garden, sea=sea, nocost=nocost, bus=bus,
                          police=police, hospital=hospital, bank=bank, mart=mart, gift=gift)
    
    # 쿼리에 데이터 삽입하는 방식
    db.session.add(new_data)
    db.session.commit()

    # id.desc -> 내림차순 정리
    # 가장 나중에 입력된 값이 선택되도록 하는 방법
    select_value = db.session.query(selectData).order_by(selectData.id.desc())[0]

    return render_template("select/select2.html",
                           select_value=select_value)

1) 준비하기

a. Flask 기본 library

from flask import Blueprint, render_template, request, url_for, redirect
from werkzeug.utils import redirect

b. db 관련

from jeju import db
from jeju.models import selectData

✅ 필요한 db를 불러오고, 사용하고자 하는 Table(selectData)를 불러오자

c. blueprint 설정

bp = Blueprint('select2', __name__, url_prefix='/select')

✅ blueprint 관련 설정

2) select2 페이지에 관한 기본설정

@bp.route('/select2', methods=('GET', 'POST'))
def show_select2():

    return render_template("select/select2.html",
                           select_value=select_value)

@bp.route('/select2', methods=('GET', 'POST'))

  • show_select2 함수의 내용을 http://127.0.0.1:5000/select/select2에 표현해주세요
  • 데이터 사용처리의 방식은 'GET', 'POST' 방식을 이용해주세요

def show_select2():

  • 해당 페이지에서 사용될 내용
  • 파이썬 코드로 작성하는 내용들

return render_template("select/select2.html", select_value=select_value)

  • render_template("select/select2.html -> select2.html로 연결해서 보여주세요
  • select_value=select_value 파이썬 코드로 할당한 select_value(뒷부분) 변수를
    select2.html에서 select_value(앞부분) 이라는 이름으로 사용하겠습니다.

3) select2 페이지에서 사용할 데이터에 관한 부분

a. 넘겨받은 데이터 정제 1 - dropdown 형태


	# alert의 history.back()이 안되는 경우 회피하는 1번째 방법
    try:
        request.form['spot2']
    except:
        return redirect('/select1')

   # 관광지 대분류
    if request.form['spot1'] == 'spot1Type1':
        spot1Type_str = '경관, 포토, 스팟'
        spot1Type = 1
    elif request.form['spot1'] == 'spot1Type2':
        spot1Type_str = '반려동물, 동반, 애견'
        spot1Type = 2
    elif request.form['spot1'] == 'spot1Type3':
        spot1Type_str = '체험, 레저'
        spot1Type = 3
    elif request.form['spot1'] == 'spot1Type4':
        spot1Type_str = '도보, 등산, 오름, 숲길'
        spot1Type = 4
    elif request.form['spot1'] == 'spot1Type5':
        spot1Type_str = '테마, 실내, 박물관, 미술, 유적지, 역사'
        spot1Type = 5
    # alert의 history.back()이 안되는 경우 회피하는 2번째 방법
    elif request.form['spot1'] == '':
        return redirect(url_for('select1.open_select1'))

try, except

  • 데이터 전송 유무에 따라 다른 값을 갖도록 함

✅ alert의 history.back()이 안되는 경우 회피하기 위한 방법

  • dropdown으로 넘어온 데이터가 넘어오지 않을 경우 select1 페이지로 이동

방법1

    try:
        request.form['spot2']
    except:
        return redirect('/select1')

방법2

	elif request.form['spot1'] == '':
        return redirect(url_for('select1.open_select1'))
  • 방법 1. request.form['spot2']의 데이터 값이 넘어오지 않을 경우
    try, except문을 통해 redirect('/select1') select1로 재연결
  • 방법 2. request.form['spot1']이 공백일 경우
    redirect(url_for('select1.open_select1')) select1_views의 open_select1의 함수가 실행되도록

b. 넘겨받은 데이터 정제 2 - checkbox

    # 숙소 추가 옵션
    pension_opt_list = ['pool', 'garden', 'sea', 'nocost', 'bus']
    for pension_opt in pension_opt_list:
        try:
            request.form[pension_opt]
            globals()[str(pension_opt)] = 1
            globals()[str(pension_opt) + '_str'] = '선택'
        except:
            globals()[str(pension_opt)] = 0
            globals()[str(pension_opt) + '_str'] = '미선택'

    # 주변 추가 옵션
    add_opt_list = ['police', 'hospital', 'bank', 'mart', 'gift']
    for add_opt in add_opt_list:
        try:
            request.form[add_opt]
            globals()[str(add_opt)] = 1
            globals()[str(add_opt) + '_str'] = '선택'
        except:
            globals()[str(add_opt)] = 0
            globals()[str(add_opt) + '_str'] = '미선택'

선택 여부에 따라 0(미선택),1(선택)변수를 만들고,
html에서 사용자가 알아듣기 쉬운 string형태의 변수를 만든다.

    pension_opt_list = ['pool', 'garden', 'sea', 'nocost', 'bus']
    for pension_opt in pension_opt_list:
        try:
            request.form[pension_opt]
            globals()[str(pension_opt)] = 1
            globals()[str(pension_opt) + '_str'] = '선택'
        except:
            globals()[str(pension_opt)] = 0
            globals()[str(pension_opt) + '_str'] = '미선택'

✅ globals()[str(pension_opt)]

  • for 문을 돌면서 변수생성 (특정 규칙을 만족하는 변수명을 만들기 위해 globals()[] 이용

try, except

  • 데이터 전송 유무에 따라 다른 값을 갖도록 함

c. sql로 데이터 저장

사용자의 선택이 위의 과정을 통해서 python 변수로 할당되었고,
이를 selectData Table에 추가하는 과정


# data 추가
    new_data = selectData(month=monthType, month_str=monthType_str,
                          spot1=spot1Type, spot1_str=spot1Type_str,
                          spot2=spot2Type, spot2_str=spot2Type_str,
                          food=foodType, food_str=foodType_str,
                          pet=petType, pet_str=petType_str,
                          pool=pool, garden=garden, sea=sea, nocost=nocost, bus=bus,
                          police=police, hospital=hospital, bank=bank, mart=mart, gift=gift)
    
    # 쿼리에 데이터 삽입하는 방식
    db.session.add(new_data)
    db.session.commit()

    # id.desc -> 내림차순 정리
    # 가장 나중에 입력된 값이 선택되도록 하는 방법
    select_value = db.session.query(selectData).order_by(selectData.id.desc())[0]

✅ 모델 컬럼에 추가하기

new_data = selectData(month=monthType, month_str=monthType_str,
                          spot1=spot1Type, spot1_str=spot1Type_str,
  • month column에 monthType의 값을 넣어라

✅ sql Table에 데이터 삽입하기

    db.session.add(new_data)
    db.session.commit()
  • db.session.add(new_data) - new_data 변수를 추가하라
  • db.session.commit()을 실행해야 해당 query로 반영 반드시 해야 테이블에 저장됨

3. 결과

1) 결과 화면

선택된 결과가 저장되는 화면은 다음과 같다.

  • SQLite Browser 이용

2) 결과 이용하기

✅ 우선 시범적인 서비스 구현임으로 다양한 사용자가 이용하지 않는 것으로 가정

✅ 가장 최근에 입력된 값을 활용하고자 함

  • 이를 선택하기 위해 id 를 내림차순으로 정리하고, 가장 첫번째 데이터를 선택해서
    select_value 변수로 활용하였다.
    # id.desc -> 내림차순 정리
    # 가장 나중에 입력된 값이 선택되도록 하는 방법
    select_value = db.session.query(selectData).order_by(selectData.id.desc())[0]
  • 쿼리 선택하기 : db.session.query(표이름)
  • 정렬하기 : .order_by(selectData.id.desc())
profile
새로운 길

0개의 댓글