티스토리 뷰
S.A (Starting Assignments) ~ 최종 설계
S.A
[내일배움캠프-팀 프로젝트] 개발 is in: S.A 작성
프로젝트 설명 프로젝트명: 개발 is in 개발자들이 모여서 글을 쓰는 곳이라는 의미를 담은 이름입니다. 핵심 목적: 개발 스택별로 구분된 게시판을 통해 개발과 관련한 꿀팁들을 공유할 수 있는
interrobang.tistory.com
최종 API
개발 is in _ API
A new tool for teams & individuals that blends everyday work apps into one.
go-tiger.notion.site
최종 DB
개발 is in _ DB
시트1 USER 컬럼,데이터 타입,제약조건,설명 id,varchar(30),PRIMARY KEY,유저 아이디 email,VARCHAR(50),UNIQUE,유저 이메일 password,VARCHAR(200),NOT NULL,유저 비밀번호(암호화) name,VARCHAR(50),NOT NULL,유저 닉네임 image,VA
docs.google.com
완성본
GitHub
GitHub - dial11/B2_Project: 22.12.02 B조 2반 프로젝트_뉴스피드 만들기
22.12.02 B조 2반 프로젝트_뉴스피드 만들기. Contribute to dial11/B2_Project development by creating an account on GitHub.
github.com
AWS 배포
개발 is in
개발자들만의 꿀팁을 나눠요
54.180.106.216
시연 영상
체크리스트 & 아쉬운 점
- 회원 기능
- ✅ 회원 가입, 로그인 구현
- ✅ 마이 페이지 프로필 수정 구현
- ✅ 비밀번호 DB에 암호화 → Bcrypt 라이브러리 이용하여 바이트 코드로 변환
- DB
- ✅ MySQL 정규화 작업
- ✅ MySQL Join 쿼리문을 활용 하여 데이터 전달
- CRUD
- ✅ 게시글 쓰기(+이미지 업로드) 기능 구현
- ✅ 게시글 글 보여주기 구현
- ✅ 게시글 글 수정 구현
- ✅ 게시글 글 삭제 구현
- GIT
- ✅ git add / commit / push 활용
- ✅ git pull / merge 활용
- 기타 기능
- ❗ Logging 데이터 확인 가능: 핸들러, 포매터의 적절한 사용으로 유의미한 로깅이 가능하도록 해야함
- ❗ Pagination 정상 동작 → ✅ 무한스크롤: 특정 페이지로 이동 가능할 수 있도록 pagination과 무한스크롤 모두 가능하면 좋을 것
- ❗ 세션 관리: 서버가 알아야할 정보들을 저장할 수 있으나 유지 조건에 관하여 고려해야함
주요 코드
카테고리, 페이지 나누기
@app.route('/board', defaults={'category': 'all', 'page': 1})
@app.route('/board/<string:category>/<int:page>')
...
perpage = 5
startat = (page - 1) * perpage
sql = f"""
SELECT b.id, b.title, b.content, b.created_at, b.updated_at, u.name, u.image, c.name_en
FROM board b
INNER JOIN `user` u
ON b.user_id = u.id
INNER JOIN category c
ON b.category_id = c.id
WHERE c.name_en = '{category}'
ORDER BY b.id desc
LIMIT {perpage}
OFFSET {startat}
"""
암호화
#회원가입시
...
userId = request.form['id']
password = request.form['password']
# 입력된 비밀번호를 바이트 코드로 변환
byte_input = password.encode('UTF-8')
hash = bcrypt.hashpw(byte_input, bcrypt.gensalt()).hex()
userName = request.form['name']
email = request.form['email']
sql = f'INSERT INTO `user` (id, password, name, email) VALUES("{userId}", "{hash}", "{userName}", "{email}");'
...
#로그인시
...
userId = request.form['id']
password = request.form['password']
# 입력된 비밀번호를 바이트 코드로 변환
byte_input = password.encode('UTF-8')
sql = f'select id,password,name,email,image,description from user where user.id = "{userId}"'
curs.execute(sql)
result = curs.fetchone()
list_result = list(result)
# 기존 저장된 값을 연산을 위해 hex에서 바이트로 변경
origin_pw = bytes.fromhex(list_result[1])
pw_check = bcrypt.checkpw(byte_input, origin_pw)
...
프로필 사진 업로드
file = request.files["file_give"]
userId = session['id']
if not os.path.isdir("static/image/user"):
os.makedirs('static/image/user') # upload/image 폴더 없을 경우 자동생성
if file:
# 매번 확장자가 jpg가 아닐수도 있으니까 파일 네임에서 가장 마지막 점으로 split을 한다
extension = file.filename.split('.')[-1]
today = datetime.now()
mtime = today.strftime('%Y-%m-%d-%H-%M-%S')
filename = f'{userId}-{mtime}.{extension}'
save_to = f'static/image/user/{filename}'
file.save(save_to)
sql = f'UPDATE `project2b2`.`user` SET image="{filename}" WHERE id="{userId}";'
curs.execute(sql)
session['image'] = filename
게시글 수정
@app.route('/boardedit/<int:board_id>/post', methods=['PATCH'])
def postBoard(board_id):
...
selectPost = request.form['category_id']
postTitle = request.form['title']
postContent = request.form['content']
# userId = session['id']
sql1 = f"""UPDATE board b
SET title = %s , content = %s , category_id = %s , updated_at = NOW()
WHERE b.id = '{board_id}' """
팀 에이스 지우님의 원픽 코드
# 회원탈퇴-----------------------------------------------------
@app.route('/delete/user', methods=['POST'])
def deleteUser():
db = pymysql.connect(
user='project2b2',
password='project2b2',
host='182.212.65.173',
port=3306,
database='project2b2',
charset='utf8'
)
curs = db.cursor()
idf = request.form['idf']
pwf = request.form['pwf']
byte_input = pwf.encode('UTF-8')
# print(idf, pwf, 2)
sql_check = f'select password from `user` where id = "{idf}" '
curs.execute(sql_check)
print(sql_check)
result = curs.fetchone()
print(result)
if result is None:
return jsonify({'msg': '회원이 아닙니다.'})
origin_pw = bytes.fromhex(result[0])
pw_check = bcrypt.checkpw(byte_input, origin_pw)
db.commit()
db.close()
if pw_check is None:
return jsonify({'msg': '회원이 아닙니다.'})
db = pymysql.connect(
user='project2b2',
password='project2b2',
host='182.212.65.173',
port=3306,
database='project2b2',
charset='utf8'
)
curs = db.cursor()
idf = request.form['idf']
pwf = request.form['pwf']
sql_check = f'delete from `user` where id = "{idf}" '
curs.execute(sql_check)
db.commit()
db.close()
return jsonify({'msg': '회원탈퇴가 되었습니다.'})
가장 마지막에 작성한 코드인데, 지금까지 작성해온 코드를 바탕으로 혼자서 작성해낸 코드라서 가장 마음에 듭니다!
완성 소감
- 변준혁: 생각보다 쉽지 않고 막히는 부분도 많았지만 완성 된 페이지를 보니 같이 고생한 팀원들이 자랑스럽습니다.
- 장빈: 팀원들 모두 고생많았고, 완성시킬 수 있어서 너무 뿌듯했습니다.
- 정지우: 이번엔 sql을 이용해 db를 사용해보았는데 처음엔 어떻게 쓰는지 모르겠어서 힘들었지만 하나의 웹사이트를 만들고보니 너무 뿌듯하고 자랑하고싶다!
- 천준기: DB 배우자마자 이렇게 활용해서 하나의 결과물을 내니 너무 뿌듯합니다.
'What I Learned > SpartaCodingClub' 카테고리의 다른 글
[내일배움캠프] 2022-12-09 TIL (0) | 2022.12.09 |
---|---|
[내일배움캠프] 2022-12-08 TIL (0) | 2022.12.09 |
[내일배움캠프] 2022-12-07 TIL (0) | 2022.12.07 |
[내일배움캠프] 2022-12-06 TIL (0) | 2022.12.06 |
[내일배움캠프] 2022.11.28. ~ 2022.12.04. WIL (0) | 2022.12.05 |
- Total
- Today
- Yesterday
- 항해+
- 24060
- 5597
- 백준
- 26069
- SQL
- 2903
- 4134
- programmer
- 2587
- Wil
- 10807
- 25501
- 25192
- 2053
- 1269
- 24313
- 13241
- 20920
- 2738
- til
- 항해 플러스
- 벡준
- 17103
- 코육대
- 24723
- Programmers
- Python
- 13909
- MySQL
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |