first commit
This commit is contained in:
commit
5caf16bb9c
132
.gitignore
vendored
Normal file
132
.gitignore
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
dist/
|
||||
eggs/
|
||||
*.egg-info/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.coverage
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# CFFI
|
||||
.cffi_cache/
|
||||
|
||||
# pycache
|
||||
__pycache__/
|
||||
27
.vscode/launch.json
vendored
Normal file
27
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
// IntelliSense를 사용하여 가능한 특성에 대해 알아보세요.
|
||||
// 기존 특성에 대한 설명을 보려면 가리킵니다.
|
||||
// 자세한 내용을 보려면 https://go.microsoft.com/fwlink/?linkid=830387을(를) 방문하세요.
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: 현재 파일",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": "Python: Streamlit",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "streamlit",
|
||||
"justMyCode": true,
|
||||
"args": ["run", "${file}"],
|
||||
"env": {
|
||||
"STATION_BUS_API_KEY1": "jEN2Laz4w1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
160
main.py
Normal file
160
main.py
Normal file
@ -0,0 +1,160 @@
|
||||
############################
|
||||
# 데이터베이스 사용 이해하기
|
||||
############################
|
||||
|
||||
# from tinydb import TinyDB, Query
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from pprint import pprint
|
||||
from userdblib import fetch_user_by_email, fetch_user_by_id, fetch_users, insert_user, update_user, delete_user, create_table, get_new_id
|
||||
|
||||
# # 데이터베이스 생성 및 연결
|
||||
# db = TinyDB('db.json')
|
||||
|
||||
|
||||
# ###########################################
|
||||
# # 데이터베이스 쿼리 함수들 #
|
||||
# ###########################################
|
||||
|
||||
# # 데이터가 없으면 샘플 데이터 추가
|
||||
# def create_table():
|
||||
# if len(db.all()) == 0:
|
||||
# users = [
|
||||
# {'id': 1, 'name': '전 John', 'email': 'john@gmail.com', 'age': 20, 'created_at': '2021-01-01 00:00:00'},
|
||||
# {'id': 2, 'name': '오 Jane', 'email': 'jane@gmail.com', 'age': 25, 'created_at': '2021-01-02 00:00:00'},
|
||||
# {'id': 3, 'name': '방 Bob', 'email': 'bob@gmail.com', 'age': 30, 'created_at': '2021-01-03 00:00:00'},
|
||||
# {'id': 4, 'name': '윤 Alice', 'email': 'alice@gmail.com', 'age': 35, 'created_at': '2021-01-04 00:00:00'},
|
||||
# {'id': 5, 'name': '김 Bill', 'email': 'bill@gmail.com', 'age': 40, 'created_at': '2021-01-05 00:00:00'},
|
||||
# ]
|
||||
# db.insert_multiple(users)
|
||||
|
||||
# def get_new_id():
|
||||
# users = fetch_users()
|
||||
# new_id = users[-1]['id'] + 1
|
||||
# return new_id
|
||||
|
||||
# def fetch_users():
|
||||
# return db.all()
|
||||
|
||||
# def fetch_user_by_id(id):
|
||||
# users = db.search(Query().id == id)
|
||||
# if len(users) == 0:
|
||||
# return []
|
||||
# else:
|
||||
# return users.pop()
|
||||
|
||||
# def fetch_user_by_email(email):
|
||||
# users = db.search(Query().email == email)
|
||||
# if len(users) == 0:
|
||||
# return []
|
||||
# else:
|
||||
# return users.pop()
|
||||
|
||||
# def insert_user(user):
|
||||
# # new_user = user_from_input()
|
||||
# db.insert(user)
|
||||
|
||||
# def update_user(user):
|
||||
# db.update(user, Query().id == user['id'])
|
||||
|
||||
# def delete_user(id):
|
||||
# db.remove(Query().id == id)
|
||||
|
||||
|
||||
|
||||
|
||||
###########################################
|
||||
# 화면 기능 함수들 #
|
||||
###########################################
|
||||
|
||||
def user_from_input():
|
||||
print("#"*30 + " 사용자 정보 입력 " + "#"*30)
|
||||
name = input("이름: ")
|
||||
email = input("이메일: ")
|
||||
age = int(input("나이: "))
|
||||
created_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
user = {'id': get_new_id(), 'name': name, 'email': email, 'age': age, 'created_at': created_at}
|
||||
return user
|
||||
|
||||
def user_from_input_update(user):
|
||||
print("#"*30 + " 사용자 정보 업데이트 " + "#"*30)
|
||||
name = input(f"이름({user['name']}): ")
|
||||
email = input(f"이메일({user['email']}): ")
|
||||
age = int(input(f"나이({user['age']}): "))
|
||||
# created_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
user = {'id': user["id"], 'name': name, 'email': email, 'age': age, 'created_at': user["created_at"]}
|
||||
return user
|
||||
|
||||
# Function to display all users
|
||||
def display_users():
|
||||
users = fetch_users()
|
||||
for user in users:
|
||||
print(f"ID:{user['id']}\n이름:{user['name']}\n전자메일:{user['email']}\n나이:{user['age']}\n가입날짜:{user['created_at']}\n")
|
||||
|
||||
def add_new_user():
|
||||
user = user_from_input()
|
||||
insert_user(user)
|
||||
print("새 사용자가 추가되었습니다.")
|
||||
|
||||
def update_existing_user():
|
||||
print("#"*30 + " 사용자 정보 수정 " + "#"*30)
|
||||
id = int(input("수정할 사용자의 ID를 입력하세요: "))
|
||||
user = fetch_user_by_id(id)
|
||||
if len(user) == 0:
|
||||
print("해당 ID의 사용자가 없습니다.")
|
||||
else:
|
||||
user = user_from_input_update(user)
|
||||
user['id'] = id
|
||||
update_user(user)
|
||||
print("사용자 정보가 수정되었습니다.")
|
||||
|
||||
def delete_existing_user():
|
||||
print("#"*30 + " 사용자 정보 삭제 " + "#"*30)
|
||||
id = int(input("삭제할 사용자의 ID를 입력하세요: "))
|
||||
user = fetch_user_by_id(id)
|
||||
if len(user) == 0:
|
||||
print("해당 ID의 사용자가 없습니다.")
|
||||
else:
|
||||
delete_user(id)
|
||||
print("사용자 정보가 삭제되었습니다.")
|
||||
|
||||
def search_user_by_email():
|
||||
print("#"*30 + " 사용자 정보 검색 " + "#"*30)
|
||||
email = input("검색할 사용자의 이메일을 입력하세요: ")
|
||||
user = fetch_user_by_email(email)
|
||||
if len(user) == 0:
|
||||
print("해당 이메일의 사용자가 없습니다.")
|
||||
else:
|
||||
print(f"ID:{user['id']}\n이름:{user['name']}\n전자메일:{user['email']}\n나이:{user['age']}\n가입날짜:{user['created_at']}\n")
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
# main 함수
|
||||
create_table()
|
||||
while True:
|
||||
print("#"*30 + " 사용자 관리 프로그램 " + "#"*30)
|
||||
print("1. 사용자 전체 조회")
|
||||
print("2. 사용자 추가")
|
||||
print("3. 사용자 수정")
|
||||
print("4. 사용자 삭제")
|
||||
print("5. 이메일로 사용자 검색")
|
||||
print("6. 종료")
|
||||
print("#"*80)
|
||||
menu = int(input("메뉴를 선택하세요: "))
|
||||
if menu == 1:
|
||||
display_users()
|
||||
elif menu == 2:
|
||||
add_new_user()
|
||||
elif menu == 3:
|
||||
update_existing_user()
|
||||
elif menu == 4:
|
||||
delete_existing_user()
|
||||
elif menu == 5:
|
||||
search_user_by_email()
|
||||
elif menu == 6:
|
||||
print("프로그램을 종료합니다.")
|
||||
break
|
||||
else:
|
||||
print("잘못된 메뉴입니다. 다시 선택하세요.")
|
||||
|
||||
39
readme.md
Normal file
39
readme.md
Normal file
@ -0,0 +1,39 @@
|
||||
[]: # BEGIN: 1c3f3c8f7c7d
|
||||
# 데이터베이스와 스트림잇 웹앱!
|
||||
* 스트림잇 기반의 웹앱 프로젝트를 수행하면서
|
||||
|
||||
## main.py 미리보기
|
||||
* 터미널환경으로 구현한 '사용자관리'하기
|
||||
|
||||
<video width="100%" controls>
|
||||
<source src="streamlit_tinydb1_1.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
|
||||
## webapp.py
|
||||
* 웹앱으로 구현한 '사용자관리' 프로그램
|
||||
|
||||
<video width="100%" controls>
|
||||
<source src="streamlit_tinydb1_2.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
|
||||
## userdblib.py
|
||||
* tinydb를 직접 액세스하는 라이브러리 모듈
|
||||
* 기본적인 CRUD 기능 구현
|
||||
* fetch
|
||||
* update
|
||||
* delete
|
||||
* create
|
||||
|
||||
## userdb.json
|
||||
* 사용자DB 파일
|
||||
* tinydb 형식으로 저장된 json데이터베이스
|
||||
* utf-8 인코딩 자체적으로 사용함.
|
||||
* 직접 파일을 수정하는 것은 권하지 않음.
|
||||
* 참조 https://github.com/msiemens/tinydb.git
|
||||
|
||||
## 설치
|
||||
```bash
|
||||
pip install streamlit --upgrade
|
||||
```
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
streamlit
|
||||
tinydb
|
||||
BIN
streamlit_tinydb1_1.mp4
Normal file
BIN
streamlit_tinydb1_1.mp4
Normal file
Binary file not shown.
BIN
streamlit_tinydb1_2.mp4
Normal file
BIN
streamlit_tinydb1_2.mp4
Normal file
Binary file not shown.
1
userdb.json
Normal file
1
userdb.json
Normal file
@ -0,0 +1 @@
|
||||
{"_default": {"1": {"id": 1, "name": "\uc804\uc0c1\ud6042", "email": "john@gmail.com", "age": 22, "created_at": "2021-01-01 00:00:00"}, "2": {"id": 2, "name": "\uc624 Jane", "email": "jane@gmail.com", "age": 25, "created_at": "2021-01-02 00:00:00"}, "3": {"id": 3, "name": "\ubc29 Bob", "email": "bob@gmail.com", "age": 30, "created_at": "2021-01-03 00:00:00"}, "4": {"id": 4, "name": "\uc724 Alice", "email": "alice@gmail.com", "age": 35, "created_at": "2021-01-04 00:00:00"}, "15": {"id": 15, "name": "\uc804\uc0c1\ud604", "email": "john@gmail.com", "age": 20, "created_at": "2023-11-09 17:47:20"}, "16": {"id": 16, "name": "\uc724\uc2e0\uc6d0", "email": "yoon@gmail.com", "age": 40, "created_at": "2023-11-09 18:58:49"}, "17": {"id": 17, "name": "\ud64d\uae38\ub3d9", "email": "hong@korea.com", "age": 29, "created_at": "2023-11-09 18:59:09"}, "18": {"id": 18, "name": "\uc720\uad00\uc21c", "email": "gw.ryu@korea.net", "age": 24, "created_at": "2023-11-09 18:59:38"}, "19": {"id": 19, "name": "\uae40\uad6c", "email": "goo.kim@korea.com", "age": 50, "created_at": "2023-11-09 20:18:45"}, "21": {"id": 21, "name": "\uc138\uc885\ub300\uc655", "email": "kingofchosun@korea.com", "age": 30, "created_at": "2023-11-10 10:45:54"}, "22": {"id": 22, "name": "\uac15\uac10\ucc2c", "email": "kang.gc@korea.com", "age": 50, "created_at": "2023-11-10 10:58:53"}}}
|
||||
54
userdblib.py
Normal file
54
userdblib.py
Normal file
@ -0,0 +1,54 @@
|
||||
from tinydb import TinyDB, Query
|
||||
from datetime import datetime
|
||||
from pprint import pprint
|
||||
# 데이터베이스 생성 및 연결
|
||||
db = TinyDB('userdb.json')
|
||||
###########################################
|
||||
# 데이터베이스 쿼리 함수들 #
|
||||
###########################################
|
||||
|
||||
# 데이터가 없으면 샘플 데이터 추가
|
||||
def create_table():
|
||||
if len(db.all()) == 0:
|
||||
users = [
|
||||
{'id': 1, 'name': '전 John', 'email': 'john@gmail.com', 'age': 20, 'created_at': '2021-01-01 00:00:00'},
|
||||
{'id': 2, 'name': '오 Jane', 'email': 'jane@gmail.com', 'age': 25, 'created_at': '2021-01-02 00:00:00'},
|
||||
{'id': 3, 'name': '방 Bob', 'email': 'bob@gmail.com', 'age': 30, 'created_at': '2021-01-03 00:00:00'},
|
||||
{'id': 4, 'name': '윤 Alice', 'email': 'alice@gmail.com', 'age': 35, 'created_at': '2021-01-04 00:00:00'},
|
||||
{'id': 5, 'name': '김 Bill', 'email': 'bill@gmail.com', 'age': 40, 'created_at': '2021-01-05 00:00:00'},
|
||||
]
|
||||
db.insert_multiple(users)
|
||||
|
||||
def get_new_id():
|
||||
users = fetch_users()
|
||||
new_id = users[-1]['id'] + 1
|
||||
return new_id
|
||||
|
||||
def fetch_users():
|
||||
return db.all()
|
||||
|
||||
def fetch_user_by_id(id):
|
||||
users = db.search(Query().id == id)
|
||||
if len(users) == 0:
|
||||
return []
|
||||
else:
|
||||
return users.pop()
|
||||
|
||||
def fetch_user_by_email(email):
|
||||
users = db.search(Query().email == email)
|
||||
if len(users) == 0:
|
||||
return []
|
||||
else:
|
||||
return users.pop()
|
||||
|
||||
def insert_user(user):
|
||||
# new_user = user_from_input()
|
||||
db.insert(user)
|
||||
|
||||
def update_user(user):
|
||||
db.update(user, Query().id == user['id'])
|
||||
|
||||
def delete_user(id):
|
||||
db.remove(Query().id == id)
|
||||
|
||||
|
||||
138
webapp.py
Normal file
138
webapp.py
Normal file
@ -0,0 +1,138 @@
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from pprint import pprint
|
||||
import streamlit as st
|
||||
from userdblib import fetch_user_by_email, fetch_user_by_id, fetch_users, insert_user, update_user, delete_user, create_table, get_new_id
|
||||
import extra_streamlit_components as stx
|
||||
|
||||
###########################################
|
||||
# 화면 함수들 #
|
||||
###########################################
|
||||
|
||||
def init_router():
|
||||
return stx.Router({"/": home, "/home": home, "/add": add_new_user, "/update": update_userinfo, "/delete": delete_userinfo, "/search": search_userinfo})
|
||||
|
||||
def selection_changed(df):
|
||||
st.write(df)
|
||||
|
||||
def show_header():
|
||||
st.title("사용자 관리 시스템")
|
||||
|
||||
def home():
|
||||
show_header()
|
||||
col1, col2, col3, col4 = st.columns(4)
|
||||
if col3.button("사용자 추가", use_container_width=True):
|
||||
router.route("/add")
|
||||
if col4.button("사용자 검색", use_container_width=True):
|
||||
router.route("/search")
|
||||
users = fetch_users()
|
||||
df = pd.DataFrame(users, columns=['id', 'name', 'email', 'age', 'created_at'])
|
||||
st.dataframe(df, use_container_width=True, hide_index=True)
|
||||
|
||||
# df에서 df["id"] + df["name"] => df["id_name"] 컬럼을 추가
|
||||
df["id_name"] = df["id"].astype(str) + ":" + df["name"]
|
||||
selected = st.selectbox("사용자 선택", df["id_name"])
|
||||
# st.write("선택된 id_name:", selected)
|
||||
st.session_state["selected"] = selected
|
||||
col1, col2 = st.columns(2)
|
||||
if col1.button("사용자 수정", use_container_width=True):
|
||||
router.route("/update")
|
||||
if col2.button("사용자 삭제",use_container_width=True):
|
||||
router.route("/delete")
|
||||
|
||||
def add_new_user():
|
||||
show_header()
|
||||
st.subheader("사용자 정보 입력")
|
||||
with st.form(key='user_form'):
|
||||
name = st.text_input(label="이름")
|
||||
email = st.text_input(label="이메일")
|
||||
age = st.number_input(label="나이", min_value=0, max_value=150)
|
||||
submitted = st.form_submit_button(label='저장하기', use_container_width=True)
|
||||
if submitted:
|
||||
created_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
user = {'id': get_new_id(), 'name': name, 'email': email, 'age': age, 'created_at': created_at}
|
||||
insert_user(user)
|
||||
st.success("저장되었습니다.")
|
||||
if st.button("사용자 목록", use_container_width=True):
|
||||
router.route("/home")
|
||||
|
||||
def update_userinfo():
|
||||
show_header()
|
||||
st.subheader("사용자 정보 수정")
|
||||
selected = st.session_state["selected"] # "1:전상현"
|
||||
user = fetch_user_by_id(int(selected.split(":")[0]))
|
||||
with st.form(key='user_form'):
|
||||
id = st.text_input(label="ID", value=user["id"], disabled=True)
|
||||
name = st.text_input(label="이름", value=user["name"])
|
||||
email = st.text_input(label="이메일", value=user["email"])
|
||||
age = st.number_input(label="나이", min_value=0, max_value=150, value=user["age"])
|
||||
created_at = user["created_at"]
|
||||
submitted = st.form_submit_button(label='저장하기', use_container_width=True)
|
||||
if submitted:
|
||||
user = {'id': int(id), 'name': name, 'email': email, 'age': age, 'created_at': created_at}
|
||||
update_user(user)
|
||||
st.success("저장되었습니다.")
|
||||
if st.button("사용자 목록", use_container_width=True):
|
||||
router.route("/home")
|
||||
|
||||
|
||||
def delete_userinfo():
|
||||
show_header()
|
||||
st.subheader("사용자 정보 삭제")
|
||||
selected = st.session_state["selected"] # "1:전상현"
|
||||
user = fetch_user_by_id(int(selected.split(":")[0]))
|
||||
with st.form(key='user_form'):
|
||||
id = st.text_input(label="ID", value=user["id"], disabled=True)
|
||||
name = st.text_input(label="이름", value=user["name"])
|
||||
email = st.text_input(label="이메일", value=user["email"])
|
||||
age = st.number_input(label="나이", min_value=0, max_value=150, value=user["age"])
|
||||
created_at = user["created_at"]
|
||||
submitted = st.form_submit_button(label='삭제하기', use_container_width=True)
|
||||
if submitted:
|
||||
delete_user(int(id))
|
||||
st.success("삭제되었습니다.")
|
||||
router.route("/home")
|
||||
if st.button("사용자 목록", use_container_width=True):
|
||||
router.route("/home")
|
||||
|
||||
def search_userinfo():
|
||||
show_header()
|
||||
st.subheader("사용자 정보 검색")
|
||||
# users = fetch_users()
|
||||
# df = pd.DataFrame(users, columns=['id', 'name', 'email', 'age', 'created_at'])
|
||||
with st.form(key='user_form'):
|
||||
search_type = st.selectbox(label="검색 유형", options=["이름", "전자메일"])
|
||||
search = st.text_input(label="검색어")
|
||||
submitted = st.form_submit_button(label='검색하기', use_container_width=True)
|
||||
if submitted:
|
||||
users = fetch_users()
|
||||
df = pd.DataFrame(users, columns=['id', 'name', 'email', 'age', 'created_at'])
|
||||
if search_type == "이름":
|
||||
df = df[df["name"].str.contains(search, case=False)]
|
||||
st.dataframe(df, use_container_width=True, hide_index=True)
|
||||
elif search_type == "전자메일":
|
||||
df = df[df["email"].str.contains(search, case=False)]
|
||||
st.dataframe(df, use_container_width=True, hide_index=True)
|
||||
|
||||
# df에서 df["id"] + df["name"] => df["id_name"] 컬럼을 추가
|
||||
df["id_name"] = df["id"].astype(str) + ":" + df["name"]
|
||||
selected = st.selectbox("사용자 선택", df["id_name"])
|
||||
# st.write("선택된 id_name:", selected)
|
||||
st.session_state["selected"] = selected
|
||||
col1, col2 = st.columns(2)
|
||||
if col1.button("사용자 수정", use_container_width=True):
|
||||
router.route("/update")
|
||||
if col2.button("사용자 삭제",use_container_width=True):
|
||||
router.route("/delete")
|
||||
|
||||
if st.button("사용자 목록", use_container_width=True):
|
||||
router.route("/home")
|
||||
|
||||
# main 함수
|
||||
create_table()
|
||||
if "selected" not in st.session_state:
|
||||
st.session_state["selected"] = None
|
||||
|
||||
router = init_router()
|
||||
router.show_route_view()
|
||||
|
||||
1
youtubedb.json
Normal file
1
youtubedb.json
Normal file
@ -0,0 +1 @@
|
||||
{"_default": {"1": {"category": "\uc0c8\uc18c\uc2dd", "title": "8\uc6d4 1\uc77c \ubd80\ud130..\uc6b0\uc774\uc2e0\uc124\uc120 \ud0c8 \ub54c \uad50\ud1b5\uce74\ub4dc \uc548 \ucc0d\uc5b4\ub3c4 \uc790\ub3d9\uacb0\uc81c", "date": "2023-07-01", "url": "https://youtu.be/Qvhukbs2pmc"}, "2": {"category": "\ud56b\ud074\ub9bd", "title": "\uc6b0\uc8fc \uccb4\ub958 \uae30\uac04\uc774 \uae38\uc5b4\uc9c0\uba70 \uc2dc\uc791\ub41c \ub204\uc6cc \uc9c0\ub0b4\uae30 \uc2e4\ud5d8", "date": "2023-07-10", "url": "https://youtu.be/URhpRjJgWlc"}, "3": {"category": "\uc778\ud130\ubdf0", "title": "\uce74\uc774\uc2a4\ud2b8\uc640 \uacf5\ub3d9\uac1c\ubc1c\ud55c '\ub2e4\ud06c \uc6f9' \uc804\uc6a9 AI '\ub2e4\ud06c\ubc84\ud2b8'", "date": "2023-06-01", "url": "https://youtu.be/6LMKuWYQCYs"}, "4": {"category": "\uc0ac\uc774\uc5b8\uc2a4", "title": "\uc6b0\uc8fc\uccad, \uc0ac\uc2e4\uc0c1 \uc5f0\ub0b4 \uac1c\uccad \ubd88\uac00..\ud56d\uc6b0\uc5f0 \ub0b4\ubd80\uc5d0\uc11c\ub3c4 \uc124\ub9bd \uc758\uacac \uc5c7\uac08\ub824", "date": "2023-05-01", "url": "https://youtu.be/7mIHv7bayMw"}}}
|
||||
Loading…
x
Reference in New Issue
Block a user