[Flask로 블로그 만들기] 2. DB 설계 및 글쓰기 구현
DB 설계
먼저 DB를 설계하기 시작했습니다. 블로그를 운영하려면 어떤 테이블과 어떤 필드가 필요할까요? 다행이 대형 서비스처럼 까다롭게 작업하진 않아도 됩니다. 블로그라는게 방문자와의 적극적인 상호 작용은 기껏해야 댓글 달기 정도이고, 나머지는 블로그 관리자가 쓴 글을 일방적으로 보여주는 역할에 그치기 때문입니다. 쇼핑몰처럼 금전적인 손해가 달린 것도 아닙니다.
아래와 같이 테이블을 구성하기로 했습니다.
글 { 순번, 작성 시간, 제목, 요약, 본문, 분류, 썸네일 주소, 라이선스}
댓글 { 순번, 작성 시간, 이름, 댓글 본문, 댓글이 작성된 포스트, 부모 댓글 번호, 해시된 비밀번호 }
특수 글 { 순번, 작성 시간, 제목, 본문, 주소(/about 등) }
순번은 곧 기본 키로 작용합니다. 겹치지 않는 값이기 때문에 키로 적합하다고 생각했습니다. 다른 서비스의 경우엔 유저 ID나 상품 ID등을 키로서 쓸 수 있었겠지만, 어차피 블로그엔 순차적으로 저장되는 글만 있으면 되고 굳이 복잡한 키를 설정할 필요도 없기 때문입니다.
무릇 어떤 소프트웨어 구조를 설계할 땐 최대한 중복 없이 작게 해야 관리가 편합니다. 코드의 함수도 한 가지 동작만 해야하듯이, 테이블도 하나의 주제로 쪼개야할 것입니다. 글과 댓글을 하나의 테이블에서 관리하기도 어렵겠지만, 생각 없이 작성하다보면 얼추 비슷한 컬럼을 쓸 것 같은 테이블은 하나로 '퉁'치게 됩니다. 제가 과거 인터넷 페이지를 APM(Apache + PHP + MySQL)으로 운영할 때, 한 테이블에 컬럼이 200개 가까이 되었습니다. 그땐 프론트엔드만 했었지 백엔드를 다뤄본 적도 없었고 PHP도 SQL도 처음이었습니다. 모 게임과 관련된 정보 공유 사이트였는데, 때를 잘 잡아서 적지 않은 사람들이 몰리는 바람에 유지보수 지옥을 느꼈었습니다. 그 뒤로 DB 테이블만은 기능별로 최대한 쪼개야겠다고 생각했습니다.
글쓰기 기능 구현
일단 댓글하고 특수 글은 다음에 구현하기로 하고, 일반 포스팅을 어떻게 써야할지 생각했습니다.
리치 텍스트 에디터 고르기
이를 위해선 적절한 '리치 텍스트 에디터'가 필요했습니다. 이는 글을 쓰면 HTML 코드로 변환해주는 역할을 합니다. 이 변환된 HTML 코드를 DB에 본문 부분에 저장하는 것이죠. 직접 구현할 수도 있지만 잘 굴러가고 좋은 바퀴가 있으면 굳이 재발명 할 필요는 없을 것입니다. 특히나 이는 사용자에게 직접 서비스되는 부분이 아닌, 블로그 관리자인 제가 글을 쓸 때만 보이는 에디터이니까요. 여전히 방문자는 외부 자원 없이 안심하고 제 블로그를 탐색할 수 있습니다.
네이버 블로그는 자체 개발한 '스마트 에디터'를 씁니다. 티스토리 또한 자체 에디터를 사용합니다. 예전에 XE, 라이믹스로 운영하던 데스크톱 애플리케이션 랜딩 사이트는 CKEditor를 사용했습니다. 제 강좌를 보고 질문할 수 있는 커뮤니티 사이트는 CKEditor도 썼었고, Toast UI Editor로 잠시 바꿨던 적도 있습니다.
지금 블로그에도 이러한 '위지윅 에디터', '리치 텍스트 에디터'가 필요했습니다. 여러 오픈 소스 에디터를 찾아보다가 결정한 것은 NHN이 만든 Toast UI Editor 였습니다. 오픈 소스는 제가 검증할 수 있어서 좋습니다. 구글 서비스를 이용하여 통계를 보내는 부분이 자바스크립트에 포함되어 있지만 옵션으로 끌 수 있었습니다. 공식 문서 첫 페이지에 구글 애널리틱스를 이용한 통계가 있음을 밝혀주었고 끄는 옵션(usageStatistics)을 제공하는 부분이 참 양심적이고 좋았습니다. 이것이 Toast UI Editor를 고른 가장 큰 이유였습니다. 게다가 MIT 라이선스라, 구글 관련된 부분을 코드에서 싹 지워서 쓸 수 있었습니다!
Toast UI Editor 사용하기
이런 에디터가 그렇듯이, JS와 CSS를 포함시킨 다음 아래와 같이 적절한 id가 담긴 div 태그 하나만 넣어주면 알아서 에디터 창이 생성됩니다.
<div id="editor"></div>
그리고 아래와 같이 필요한 옵션을 공식 문서(GitHub Pages)를 참고하여 자바 스크립트로 지정해주어야 합니다.
const Editor = toastui.Editor;
const editor = new Editor({
el: document.querySelector('#editor'),
height: 'Calc(100% - 70px)',
previewStyle: 'tab',
initialEditType: 'wysiwyg',
usageStatistics: false
});
물론 그 후에 추가로 옵션을 더 넣긴 했습니다. 그럴듯한 Toast UI Editor 창이 완성되었습니다.
메타데이터 설정 폼 만들기
포스트 정보, 즉 '제목' 이라던가 '썸네일' 등을 정할 수 있는 폼을 만들어야 합니다. 어차피 저만 보는 화면이므로, 디자인 신경쓰지 않고 최대한 간단하게 만들어줍니다.
발행 버튼을 누르면 별도의 주소로 POST 요청을 보내어서, Flask에서 POST 된 정보를 잘 모아 DB에 적어줍니다. Flask에선 유효성 검사를 한 다음에 썸네일을 서버에 업로드하고, pymysql 라이브러리를 이용해서 앞서 언급한 필드 — 순번, 작성 시간, 제목, 요약, 본문, 분류, 썸네일 주소, 라이선스 — 를 테이블에 적습니다.
본문으로 작성한 글의 HTML 코드는 Editor 객체의 getHTML()
함수를 통해 불러올 수 있으므로, 폼에 hidden 타입의 요소를 하나 넣은 후 아래와 같이 발행 버튼의 onSubmit
이벤트에 그 요소의 값을 바꿔주는 동작을 넣어주기만 하면 됩니다. 이렇게 하면 그 hidden 요소의 name을 통해 POST 된 값을 쓸 수 있습니다.
onsubmit="document.getElementById('post-content').value = editor.getHTML();"
이제 DB에 포스트가 저장됐으니, 사용자가 n번 포스트를 요청할 때 순번이 n인 포스트의 내용을 불러와 보여주면 되는 것이죠.
다음 내용으로 이어집니다.
시리즈: Flask로 완전 처음부터 블로그 만들기
2. DB 설계 및 글쓰기 기능 구현 (현재)