3 분 소요

1단계 파일구조

├── templates
│   ├── detail_sample.html  #샘플 표시 방식
│   ├── list_sample.html    #샘플 표시 방식
│   └── user_detail.html    #유저 개인 정보 표시
|   └── user_list.html      #유저 개인 정보 표시
└── db.py
└── model.py
└── mainlist.py
└── model.py

사용

SQL Alchemy - SQL 사용하기위해 쓰는 프로그램 언어 Starlette 경랑 아스키 프레임 워크

2. 자세한 파일 설명

db.py 데이터베이스 연동하는 코드이다

# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

user_name = 데이터베이스 유저 이름
user_pwd =  데이터 유저 이름
db_host = 데이터 베이스 주소
db_name = 데이터 베이스 이름

DATABASE = 'mysql://%s:%s@%s/%s?charset=utf8' % (
    user_name,
    user_pwd,
    db_host,
    db_name,
)

ENGINE = create_engine(
    DATABASE,
    encoding="utf-8",
    echo=True
)

session = scoped_session(
    sessionmaker(
        autocommit=False,
        autoflush=False,
        bind=ENGINE
    )
)

Base = declarative_base()
Base.query = session.query_property()

model.py 데이터 베이스 모델을 정의하는 코드이다

# coding: utf-8
from sqlalchemy import Column, Integer, String
from pydantic import BaseModel
from db import Base
from db import ENGINE


class UserTable(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(30), nullable=True)
    age = Column(Integer)


class User(BaseModel):
    id   : int
    name : str
    age  : int


def main():
    # Table 없으면 생성
    Base.metadata.create_all(bind=ENGINE)

if __name__ == "__main__":
    main()

mainlist.py 기본 FastAPi 틀이다

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

from typing import List
from starlette.middleware.cors import CORSMiddleware

from db import session
from model import UserTable, User


templates = Jinja2Templates(directory="templates")

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
async def root():
    return {"message": "/users 에서 사용자관리"}


# ----------API 정의------------
@app.get("/users", response_class=HTMLResponse) #기본 화면 입력 보여주기
async def read_users(request: Request):
    print("read_users >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    context = {}

    users = session.query(UserTable).all()

    context['request'] = request
    context['users'] = users

    return templates.TemplateResponse("user_list.html", context)


@app.get("/users/{user_id}", response_class=HTMLResponse) #특정 유저 값 읽어오기
async def read_user(request: Request, user_id: int):
    print("read_user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    context = {}

    user = session.query(UserTable).filter(UserTable.id == user_id).first()
    print(user.name)
    context['name'] = user.name
    context['age'] = user.age
    context['request'] = request

    return templates.TemplateResponse("user_detail.html", context)


@app.post("/users")
async def create_user(users: User):  #유저값 추가하기
    print("create_user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    # data = await request.json()

    userlist = list(users)
    uname = userlist[1][1]
    uage = userlist[2][1]

    user = UserTable()
    user.name = uname
    user.age = uage

    session.add(user)
    session.commit()

    return { 'result_msg': f'{uname} Registered...' }


@app.put("/users")
async def modify_users(users: User):  #유저값 수정하기
    print("modify_user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")

    userlist = list(users)
    uid = userlist[0][1]
    uname = userlist[1][1]
    uage = userlist[2][1]

    user = session.query(UserTable).filter(UserTable.id == uid).first()
    user.name = uname
    user.age = uage
    session.commit()

    return { 'result_msg': f"{uname} updated..." }


@app.delete("/users")
async def delete_users(users: User):  #유저값 삭제하기
    print("delete_user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")

    userlist = list(users)
    uid = userlist[0][1]

    user = session.query(UserTable).filter(UserTable.id == uid).delete()
    session.commit()

    return {'result_msg': f"User deleted..."}



user_list.html 데이터 베이스에서 받은 데이터를 CRUD 해주는 페이지이다

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User list</title>

        <script>

        function getCookie(name) {
            var cookieValue = null;
            if (document.cookie && document.cookie !== '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    const cookie = cookies[i].trim();
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) === (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
        var csrftoken = getCookie('csrftoken');

        var xhr;

        // Ajax로 등록
        function postUser() {

            var uname = document.getElementById('username_').value;
            var uage = parseInt(document.getElementById('userage_').value);

            var data = { id: 0, name: uname, age: uage };
            var jsonstr = JSON.stringify(data);

            //alert(jsonstr);
            //return false;

            xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    var data = xhr.responseText;
                    var obj = JSON.parse(data);

                    var node = document.createElement("DIV");
                    var textnode = document.createTextNode(uname + " - " + uage + " added...");
                    node.appendChild(textnode);
                    document.getElementById("usertable").appendChild(node);

                    //alert(obj.name + " registered...");
                }
            };
            xhr.open("POST", "/users");
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
            xhr.send(jsonstr);
        }

        // Ajax로 수정
        function putUser(elem) {

            var userid = parseInt(elem.getAttribute('userid'));
            var uname = document.getElementById('username_'+userid).value;
            var uage = parseInt(document.getElementById('userage_'+userid).value);

            var data = { id: userid, name: uname, age: uage }
            var jsonstr = JSON.stringify(data);

            //alert(jsonstr);
            //return false;

            xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    var data = xhr.responseText;
                    var obj = JSON.parse(data);
                    //alert(uname + " modified...");
                    document.getElementById('username_'+userid).style.color = "#FF6600";
                    document.getElementById('userage_'+userid).style.color = "#FF6600";
                }
            };
            xhr.open("PUT", "/users");
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
            xhr.send(jsonstr);
        }


        // Ajax로 삭제
        function deleteUser(userid) {

            if (confirm("삭제 하시겠습니까?") == false) {
                return false;
            }

            var data = { id: userid, name: '', age: 0 }
            var jsonstr = JSON.stringify(data);

            xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    var data = xhr.responseText;
                    var obj = JSON.parse(data);

                    document.getElementById('userbox_'+userid).remove();
                    //alert(obj.result_msg);
                }
            };
            xhr.open("DELETE", "/users");
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
            xhr.send(jsonstr);
        }

    </script>
</head>
<body>

    <div style="padding:10px;">
        <a href="/">HOME</a>
    </div>

    <h1 style="padding:10px;">User list</h1>
    <div style="margin:20px 0">
        <input type="text" id="username_" value="사용자" />
        <input type="text" id="userage_" value="1" />
        <button onclick="postUser()">등록</button>
    </div>
    <div  id="usertable">
    <table width="100%" border="1" cellpadding="0" cellspacing="0">
    
        <tr style="padding:10px;border-top:solid 1px #3388cc;">
            <td>
            No user...
            </td>
        </tr>
    
    </table>
    </div>

</body>
</html>

참고

  1. https://www.youtube.com/watch?v=N8i4GcRRkV8&t=1230s
    • 해당 관련으로 FastAPI 관련 설명이 동영상으로 설명이 잘 되어 있다.
    • http://cop.projectcafe.kr:3100/gidatalab 31번쨰 참고

댓글남기기