본문 바로가기

여러가지/테스트

[실습] Address Book

● 구조

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

address_book/
├── app.py
├── templates/
│   └── home.html
│   └── add_contact.html
├── requirements.txt

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

● 파일

(파일) requirements.txt

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Flask
Flask-SQLAlchemy

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

(실행) # pip3 install -r requirements.txt

※ 필수 패키지 설치하는 파일입니다.

 

(+) pip3 : python3.x 버전 패키지 관리 도구

 

(파일) app.py

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

# flask, flask_sqlalchemy 모듈 패키지 불러오기

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

# flask_sqlalchemy : 데이터베이스 생성 시 사용
from flask_sqlalchemy import SQLAlchemy

 

# Flask 애플리케이션 인스턴스(app) 생성

app = Flask(__name__)

# SQLite 데이터베이스(contacts.db)사용 설정

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///contacts.db'

# SQLAlchemy 이벤트 시스템 비활성화
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# SQLAlchemy 인스턴스(db) 생성 및 Flask 애플리케이션 인스턴스 (app) 연결
db = SQLAlchemy(app)

 

# 데이터베이스 모델(Contact) 정의
class Contact(db.Model):

    # 각 컬럼 정의
    id = db.Column( db.Integer, primary_key=True)
    name = db.Column( db.String(80), nullable=False)
    phone = db.Column( db.String(20), nullable=False)
    email = db.Column( db.String(120), nullable=False)
     

    # 객체의 문자열 표현 반환
    def __repr__(self):

        return f'<Contact {self.name}>'

 

# 데이터베이스 생성 및 초기화
with app.app_context():
    db.create_all()

 

# 라우팅
@app.route('/')

# 특정 경로(ex. /) 진입 시, 불러올 함수(ex. index) 생성 및 지정 
def home():

    # Contact 모델의 모든 쿼리 조회
    contacts = Contact.query.all()

    # .html 파일 렌더링
    return render_template('home.html', contacts=contacts)

 

# methods=['GET', 'POST'] : 허용된 HTTP 메소드 지정
@app.route('/add', methods=['GET', 'POST'])
def add_contact():

    # POST 받을 시, 아래의  수행
    if request.method == 'POST':

        # 브라우저로부터 전송된 form의 각 값을 각 변수에 저장
        name = request.form['name']
        phone = request.form['phone']
        email = request.form['email']
        # 새로운 값의 데이터베이스 모델(Contact)을 변수에 저장
        new_contact Contact(name=name, phone=phone, email=email)

        # 변수를 통해 데이터베이스에 새로운 값 추가
        db.session.add(new_contact)

        # 영구 저장
        db.session.commit()

 

        # index 함수로 리다이렉션

        return redirect(url_for('home'))

    # POST 받기 전, .html 파일 렌더링
    return render_template('add_contact.html')

if __name__ == '__main__':

    # 모든 호스트 / 포트 / 디버그 모드 애플리케이션 실행

    app.run(host='0.0.0.0', port=5000, debug=True)

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

(+) 디버그 모드 : 코드 변경 시 자동으로 서버 재시작 및 오류 발생 시 디버깅 정보 제공

 

(파일) home.html

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Address Book</title>
</head>
<body>
    <h1>Address Book</h1>
    <a href="{{ url_for('add_contact') }}">Add New Contact</a>
    <ul>

        # Jinja2의 for 루프 사용하여 contacts 리스트 순회하며 각 contact 객체 처리
        {% for contact in contacts %}
            <li>{{ contact.name }} - {{ contact.phone }} - {{ contact.email }}</li>

        # Jinja2의 for 루프 끝
        {% endfor %}
    </ul>
</body>
</html>

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

(파일) add_contact.html

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Address Book</title>
</head>
<body>
    <h1>Add Contact</h1>
    <form action="{{ url_for('add_contact') }}" method="POST">
        <label for="name">Name:</label>
        <input type="text" id="name" name="name" required><br>
        <label for="phone">Phone:</label>
        <input type="text" id="phone" name="phone" required><br>
        <label for="email">Email:</label>
        <input type="email" id="email" name="email" required><br>
        <button type="submit">Add</button>
    </form>
    <a href="{{ url_for('home') }}">Back to Home</a>
</body>
</html>

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

<form> 태그 : 사용자가 입력한 데이터 서버로 전송하기 위한 폼 정의

 

[참고] Python3 가상 환경 실행

https://uyijune15.tistory.com/223

 

[정리] Python3 가상 환경

Step1.  가상 환경 생성# python3 -m venv venv Step2. 가상 환경 활성화# (Linux) source venv/bin/activate# (Windows) venv\Scripts\activat Step3. 가상 환경 비활성화# deactivate

uyijune15.tistory.com

 

● 실행

Step1. 선수 작업 진행

[참고] https://uyijune15.tistory.com/222

 

[정리] 선수 작업

1) python3 설치# yum install -y python3 2) 최신 패키지 업데이트# yum -y update# pip install --upgrade pip 3) 필요 패키지 설치# yum -y install gcc# pip3 install gunicorn

uyijune15.tistory.com

 

Step2. 방화벽 설정

# firewalll-cmd --permanent --add-port=5000/tcp

# firewall-cmd --reload

 

Step3. 작업 디렉토리 이동

# cd address_book

 

Step4. 필수 패키지 설치

# pip3 install -r requirements.txt

 

Step5. 실행

# gunicorn -w 4 -b 0.0.0.0:5000 app:app

# python app.py

 

 

● 테스트

(브라우저) http://<-IP->:<-PORT->

'여러가지 > 테스트' 카테고리의 다른 글

[참고] sqlite3 데이터베이스  (0) 2024.06.15
[실습] Address Book - delete 기능 추가  (0) 2024.06.15
[참고] HTTP 메소드  (0) 2024.06.15
[참고] Python3 가상 환경  (0) 2024.06.15
[참고] 선수 작업  (0) 2024.06.15