블록 체인은 이미 뜨거운 IT 화제 중 하나다. 

알아가면 알아갈 수록 이 기술에 대한 발전 가능성이 엄청나다는 사실을 깨닫고 있다.

 

블록 체인에 대해 이해하기 위해 필요한 개념들을 정리할 필요가 있다.

 

블록 체인을 이해하기 위해서는 분산 시스템을 이해해야한다.

 

분산 시스템

컴퓨터 패러다임 중 하나로, 둘 이상의 노드가 공동으로 결과를 얻기 위해 조율하며 함께 동작하는 방식이다.

 

여기서 노드란, 분산 시스템의 개별 참가자로 정의하며 쉽게 말해서 하나의 컴퓨터, 하나의 참여자를 뜻한다.

여러 참여자가 업무를 같이 나눠서 처리하는 것이다. 여기서 사람들을 쉽게 믿지 못하는 사람들은 자연스레 의문이 들 수 있다.

 

'일을 나눠서 한다고? 그러면 그 중 한 명이 나쁜 놈이면? 모든 일이 엉망이 되거나 결과가 그 나쁜 놈이 원하는 대로 만들어질 수 있지 않을까?'

 

아주 자연스러운 발상이고 이 문제가 오래 전부터 분산 시스템을 개발해오던 사람들이 늘 가지고 있던 고민이다. 이런 악의적인 노드(나쁜 놈)을 비잔틴 노드라고 부른다. 분산 시스템에서는 비잔틴 노드 문제를 해결하기 위해 다양한 알고리즘을 개발해왔다. (이런 알고리즘 종류와 개념들만 쭉 훑어봐도 사람들이 얼마나 진지하게 고민해왔는지 느낄 수 있다.)

 

분산 시스템에서 필요한 조건

그렇다면 좋은 분산 시스템에는 어떤 특징들이 있어야할까?

 

분산 시스템에서는 도달하고자하는 3가지 속성이 있다.

 

1. 정합성 (Consistency)

2. 가용성 (Availability)

3. 분할 허용성 (Partition tolerance)

 

와... 또 딱딱한 이야기한다. 생각하겠지만, 이는 이름일 뿐이다.

하나하나 쉽게 풀어서 알아보면 어찌보면 당연한 이야기들 뿐이다.

 

아주 빠르고 간단하게 풀어보도록 하겠다.

 

1. 정합성 (Consistency)

분산 시스템에 있는 모든 노드들이 같은 데이터를 가지고 있게 하는 것이다. 다 같이 해킹 스터디를 하는데, 혼자 국어책을 가지고 와서 공부하는 학생을 생각해보자. 다른 사람들은 해킹 책을 나눠가며 읽고 토의하는 와중에, 혼자만 딴 소리하게 될거고 스터디는 엉망이 될 것이다.

 

중앙 집중 방식의 시스템에서는 운영하는 서버가 이를 관리한다. 서버가 공통의 정보를 가지고 있고 클라이언트들이 그 정보를 받아서 사용한다. 즉, 최신화되어있는 데이터는 서버가 가지고 있다.

 

그런데, 분산 시스템은 이런 중앙 서버가 없이 서로서로 각자 알아서 최신화된 데이터를 가지고 있어야한다는 것이다.

 

2. 가용성 (Availability)

분산 시스템에서 각각의 노드가 정상적으로 요청을 처리하고 응답할 수 있어야한다는 말이다. 즉, 각각의 노드에서 데이터를 받아 사용할 수 있고 또한 각각의 노드들은 서로의 요청에 응답할 수 있다. 쉽게 말하면 각 노드가 띵가띵가 놀지 않고 열심히 일을 한다는 말이다!

 

3. 분할 허용성 (Partition tolerance)

분산 시스템은 네트워크 장애로 인해 통신이 안되거나 어떤 노드가 장애가 될 때 그 문제되는 부분을 제외하고 나머지 그룹들 끼리라도 계속 올바르게 동작해야한다는 것이다. 이 분할 허용성 또한 굉장히 중요한데, 만약 분산 시스템이 1000개의 노드로 이루어져있다고 생각하면 이 1000개가 모두 잘 동작해야한다는 건데, 하나라도 문제가 생기거나 인터넷이 끊겼을 때 전체 시스템이 동작을 못한다면 많은 사람들이 쓰지 못하게 된다. 분산 시스템에 많은 노드들을 포함시키려면 굉장히 중요한 성질 중 하나다.

 

분산 시스템은 이 3가지 속성을 만족시키기 위해 개발자들이 열심히 머리를 써왔다.

 

그러나 허무한 결과가 나왔는데, 바로 그게 CAP 정리다.

 

CAP 정리 (Consistency - Availability - Partition tolerance)

브루어의 정리(Brewer's theorem)이라고도 하는데, 에릭 브루어(Eric Brewer)가 1998년에 가설로 내세웠고, 그걸 2002년 세스 길버트(Seth Gilbert)와 낸시 린치(Nancy Lynch)에 의해 입증되었다.

 

[CAP Theorem]
어떤 분산 시스템이든 정합성과 가용성, 분할 허용성을 동시에 만족시킬 수 없다.

 

 

띠용..?

분산 시스템에서 만족해야할 성질 3가지를 선정하고 이를 향해 노력해왔건만...

이건 잡지 못하는 무지개와 같...

 

침착하게 살펴보자...

그 내용은 다음과 같다.

 

노드가 2개인 분산 시스템을 가정하고 설명이 시작된다.

 

CAP는 다음의 내용들이다.

- 정합성은 두 노드가 동일한 공유 상태인 경우, 즉 두 노드가 동일하게 데이터의 최신 사본을 갖고 있는 경우에 달성된다.

- 가용성은 두 노드가 모두 가동 중이고 최신 데이터 사본으로 응답하는 경우에 달성된다.

- 분할 허용성은 두 노드 간에 통신이 끊어지지 않고, 서로 통신 가능한 경우에 달성된다.

 

여기서 분할이 발생해서 두 노드가 서로 통신할 수 없는 경우를 생각해본다.

 

 

 

이때 하나의 노드에 새로운 데이터가 전달되면 엄청난 문제가 발생된다. 통신 두절이기 때문에 하나의 노드에만 업데이트 될 수밖에 없다.

 

 

이 경우에 해당 노드가 업데이트를 수용하면, 네트워크에서 이 노드 하나만 업데이트되므로 정합성을 잃게된다.

 

그런데 반대로 노드가 업데이트를 거절하면, 가용성을 잃는 결과를 초래한다.

 

즉 여기서 분할 가능성을 성립하는 순간 둘 중에 하나는 탈락이다.

 

하... 그렇다면 분산 시스템은 여기서 끝이란 말인가...

 

이때 블록 체인이 등장하는데..!

신기하게 이 블록 체인은 CAP를 모두 만족해버린다.

 

?! 아! 그러면 CAP 정리는 거짓이었구나!

 

또 그렇지 않다. 블록 체인은 CAP를 만족하기 위해 정합성을 아주 잠깐 포기한다.

정합성이란 모든 노드가 똑같은 최신 데이터를 가지고 있어야한다는 것이다.

 

그런데, 블록 체인의 경우 정합성이 깨지는 것을 잠깐 눈감아준다.

대신 시간이 지날 수록 모든 노드들이 같은 데이터를 가질 수 밖에 없게 되는 정말 신기한 마법 같은 일을 구현해냈다.

 

그렇게 인간들의 CAP를 향한 노력의 산물이 블록 체인이다.

 

 

 

* 추가할 기능 구현 (게시판)

- 조회수 조작 방지 기능



* 추가할 기능 구현 (인증)

- 소셜 인증


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


  조회수 조작 방지에 관해 어떻게 해결해야할까 고민하던 중 오늘 자료실의 좋아요 기능을 만들면서 해결책이 가늠이 잡혔다. 하지만 이번 일지에서는 구현하지 못하였다.


  이번 일지에서는 자료실을 추가하였다. 게시판과 똑같다. 다만 파일 업로드, 다운로드 기능이 새로웠고, 조회수 대산 좋아요 기능을 추가하였다.




  자료실 모델이다.


< model >


  게시판과 똑같다. 다른 점은 FileField 가 추가되었다.


< urls.py >


  게시판과 같고 다른점은 좋아요 기능 구현을 위한 url이 추가되었다.


자료실의 모습이다.


< 자료실 모습 >


  게시판과 같은 모습이지만 맨 오른쪽에 좋아요 수를 보여주고 있다.


자료실 업로드는 큰 어려움이 없었는데 업로드된 파일을 다른 사용자가 다운로드해주는 기능을 추가해야했다.


< 다운로드 기능 >


  DEBUG 모드에서는 단순히 URL 주소를 넘겨주면 직접 접근이 가능하다. 하지만 실제 배포하였을 때는 직접 접근이 안되기 때문에, 다운로드 기능을 추가해주어야한다. file_url 에서 맨 앞 글자를 지운 이유는 이상하게도 업로드된 사진을 웹에 보여주는 것과는 동작이 달랐기 때문인데 문제를 분석하다보니 url 다루는 차이가 있었다.


  file의 경우 앞에 / 문자가 없어야 잘 동작했고 사진의 경우 / 문자가 있어야 잘 동작했다. 그래서 / 문자를 settings.py 에서는 넣어서 설정을 하고 파일 다운로드 기능에서는 위와 같이 [1:] 을 사용해 맨 처음 문자를 빼고 넣어주었다.



< 다운로드 >


  다운로드를 클릭하니 다운로드 되었다.



< 다운로드 된 모습 >



  다음으로 좋아요 기능이다.


< like_tools 추가 >


  먼저 사용자의 프로필에 like_tools를 추가해주었다. 이는 ManyToMany 필드로 연결했다.



< 토글 기능 >


  토글기능은 현재 사용자의 좋아요 리스트에서 해당 포스트 자료가 존재하면 remove 해주고 존재하지 않으면 add로 해당 포스트 자료를 추가해준다.



< html >


  마찬가지로 좋아요 리스트에 있다면 좋아요를 누른것이므로 Unlike를 출력해주고 없으면 아직 누르지 않은 것으로 Like 를 출력하여 토글 버튼이 되도록 하였다.



< 좋아요 클릭 >



< 좋아요 클릭한 모습 >


  좋아요를 클릭하면 Unlike로 바뀐다.



< 좋아요 수 출력 >


  좋아요 수는 해당 자료를 좋아요 누른 사람들의 수를 count 하여 출력해준다.


* 서버 호스팅

- MySQL 연동

- AWS 구축 및 환경 구축

- 호스팅 및 DNS 등록


* 추가할 기능 구현 (게시판)

- 조회수 조작 방지 기능



* 추가할 기능 구현 (인증)

- 소셜 인증


* 추가할 기능 구현 (게시판)

- 댓글 수정기능 -> 댓글 삭제 기능

- 조회수 조작 방지 기능

- 게시글 삭제 기능


* 추가할 기능 구현 (인증)

- 소셜 인증


==========================================


  댓글 수정말고 댓글 삭제 기능을 넣었다. 댓글 같은 경우 수정할 바에 차라리 지우고 다시 쓰도록 의도하였다.


  먼저 작업 들어가기전에 갑자기 아이디어가 떠올라 개선한 점이 있다. 바로 리다이렉트부분이다. 기존 같은 경우 게시글을 수정하거나, 게시글에서 댓글을 작성한 후에 게시글 리스트로 리다이렉트 된다. reverse를 써서 제자리에 오도록 하려했으나 (F5기능) circular import 문제 때문에 구현하지 못했었다.


  그런데 그냥 템플릿에 넘겨주면 되지 않나? 라는 생각이 들어 이 부분을 해결하였다.


< render로 변경 >


  템플릿을 지정해주고 context 안에 post를 담아서 보내주었다.



< 개선된 게시글 >


  이제 이 자리에서 바로 글을 수정해도 이 페이지며, 댓글을 달아도 이 페이지로 남는다.


  그런데 이상한 점을 추가적으로 포착했다. 바로 개행이 안된다는 점이다. 위 사진을 보면 분명 내가 Update 마다 줄을 바꿔줘서 넣었는데 개행처리가 안됬다.


  이 점에 대해 검색을 해보니 HTML에서 개행을 처리 안해서 그렇다고 한다. 개행을 <br> 로 바꿔주면 된다. 여기서 linebreaksbr 을 사용하면 <br>로 바뀐다고 한다.



< linebreaksbr >


  확인해보면 다음과 같다.


< 개행처리 되는 모습 >



  이제 본격적으로 구현하고자 하는 기능 구현이다. 먼저 게시글 삭제 기능이다. 이 기능은 직접 구현하지 않고 CBV를 이용하여 구현하였다. 다만 함부로 삭제되면 안되므로 현재 로그인된 사용자가 게시글을 작성한 사람과 같은지 검증하기 위해 filter를 이용하여 검색된 쿼리만 삭제하도록 구현하였다.


< PostDeleteView >


  테스트해본다.!


< 삭제 테스트 >



< 삭제 확인 팝업 >


  정말 삭제할 것인지 물어본다.


  그 후 정말 삭제할 것인지 다시 한번 물어보는데 이는 DeleteView에 있는 기본 기능에서 템플릿만 만들어서 이어주었다.


< 재재확인 >



< 삭제된 글 >


  글이 정상적으로 삭제 되는 것을 확인하였다.



  다음으로 댓글 삭제이다. 댓글 삭제도 CBV를 이용하고 싶었으나, pk 종류가 두개가 들어오는데 이를 처리하는 부분에서 계속 에러가 나서 직접 view를 작성하였다.



< comment_delete view >


  post와 comment 둘 다 얻는다. 그 이유는 comment는 삭제하기 위한 것이고, post는 다시 원래 있던 페이지로 돌아가기 위해서이다.



< 댓글 삭제 테스트 >


  맨 위의 댓글을 지워보았다.



< 댓글 삭제 확인 >



  댓글이 정상적으로 삭제되었다. 




* 추가할 기능 구현 (게시판)

- 조회수 조작 방지 기능



* 추가할 기능 구현 (인증)

- 소셜 인증


* 추가할 기능 구현 (게시판)

- 댓글 기능

- 조회수 기능

- 게시글 삭제 기능


* 추가할 기능 구현 (인증)

- 소셜 인증


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


  오늘은 댓글 기능과 조회수 기능을 추가하였다.


  추가적으로 게시판의 모양을 테이블로 조금 더 그럴싸하게 만들었다.


< 게시판 표 작성 >


  게시판 모델 HTML을 가져와 사용했고, 컨텐츠는 전달받는 post에서 뽑아서 뿌려주었다.



< 게시판 모양 >


  다음으로 댓글 기능을 추가하였다.


다음은 댓글 Model이다.


< Comment Model >


  writer를 Profile과 연결해주었다. 또 post와도 연결해주었다.


  다음은 템플릿에서 댓글 출력 코드이다. 


< 댓글 출력 코드 >


  Comment 모델에서 post를 외부키로 연결할 때 related_name을 comments로 정의해주어서 comments로 접근할 수 있다.


  여기에 사진은 캡쳐하지 않았지만 comment.comment_writer로 닉네임을 출력할 수 있었던 이유는 내가 Profile 모델을 정의하면서 __str__ 을 overwrite해서 닉네임을 출력하게 만들었기 때문이다.


< 댓글 출력 화면 >



  다음으로 댓글 쓰기 기능을 만들었다. 쓰기의 경우 기존 detail 보는 템플릿에서 폼을 추가해주고 해당 폼을 처리해줄 view를 만드는 과정으로 진행했다.



< form 생성 >


  post 와도 외부키가 연결되어있기 때문에 post의 pk가 필요하다.



< comment_write view >


  POST 메서드일 경우만 처리하게 만들었다. 이 경우 post를 pk로 뽑아내고 현재 로그인한 사용자의 user를 가져와 연결된 Profile을 작성자와 연결해준다. 그 후 각 내용을 Comment 로 생성해주면 된다.



< 테스트 댓글 작성 >



< 댓글 작성 확인 >


  다음으로 댓글의 개수를 출력해주었다.


< 댓글 수 >


  이 댓글 수를 새주는 것은 all 대신 count를 이용하면 되었다.



  다음으로! 조회수 기능이다.! 

나는 Detail View(CBV)를 사용하였는데, 인터넷에 보니 CBV를 사용할 경우 처리해야할 게 많아서 보통 다른 lib를 이용한다고 들었다. 그런데 내가 일단 구현해 보았다.



< 조회수 증가 함수 생성 >


  @property를 이용하면 템플릿에서도 사용할 수 있다. 조회수를 1 늘리고 저장한다.



< 템플릿에 삽입 >


  이렇게 되면 해당 화면이 불려질때마다 해당 post의 조회수가 1씩 증가한다.



< 조회수 증가 테스트 >

  


  테스트해보니 문제가있었다...

해당 템플릿이 로드 될 때마다 조회수가 증가하다보니, F5를 연달아 누르면 조회수가 막 올라간다... 


  이 기능을 세션을 가지고 처리했던 것 같은데 자세히 다시 알아보고 처리해야겠다.



* 추가할 기능 구현 (게시판)

- 댓글 수정기능

- 조회수 조작 방지 기능

- 게시글 삭제 기능


* 추가할 기능 구현 (인증)

- 소셜 인증



  Django 프로젝트에서 게시판 프로젝트를 시작한다. 인증 부분에서 소셜인증, 회원정보 수정을 제외하고는 전부 구현하였다. (나머지 기능은 차차 구현할 것이다.)



  오늘은 게시판에서 게시글들을 출력하고 게시글을 들어가서 확인하는 것까지 구현하였다.


  먼저 시간 설정을 해주었다. Post 모델을 정의하여 게시글을 만들었다. 이 때 작성일시를 자동으로 현재 날짜시간을 기록하게 하였는데, 이 때 settings.py 에서 설정해주어야할 것이 있다.


< settings.py 설정 >


  이 변수를 False로 설정해야 settings.py에서 설정한 시간대를 프로젝트 전체에서 사용할 수 있다.



  Post 모델을 정의하였다.


< Post 모델 >


  이 모델은 게시글이다. 작성자를 CharField로 설정한 이유는 사용자의 프로필에서 nickname을 가져와서 문자열로 저장하려고 하기 위해서이다.



< urls.py >


  다음으로 urls.py를 설정해준다. 기본적인 게시글 리스트와 디테일을 만들었다. 그리고 추가적으로 글 쓰기와, 글 수정을 만들었다.



< CBV를 이용한 View >


  글 리스트와 디테일은 CBV를 이용하여 쉽게 구현하였다.



< 게시글 목록 보기 >



< 게시글 자세히 보기 >


  다음으로 글 작성하는 것을 만들었다. CreateView (CBV)를 이용할 수 있었지만, 나는 작성자에 사용자의 프로필에 있는 닉네임을 넣어줄 것이고 또한 메세지를 출력해주고 싶었기에 직접 view를 만들었다.


< post_write view >


  글쓰기 뷰를 만들고 테스트해보았다.



< 글 작성 테스트 >



< 글 작성 성공 메세지 알람 >


< 글 작성 리스트에서 확인 >



< 글 작성 내용 보기로 확인 >



  다음으로 작성한 글에 대한 내용을 수정하는 것이다.


< post_update view >


  여기서 인증부분이 필요했다. 글은 아무나 수정하면 안되기 때문이다. 로그인한 사용자의 정보에서 프로필을 가져와 프로필에 있는 닉네임과 게시글 작성자를 비교하여 같으면 수정을 허락하고 같지 않으면 경고를 해준다.



< 글 수정 테스트 >



< 글 수정 성공 메세지 알람 >


< 글 수정 확인 >


  오늘 일지의 마지막으로는 유저 확인기능에 대해서 정리할 것이다. 게시글에서 작성자가 나오는데 해당 작성자에 대해 알아볼 수 있는 기능을 추가하기로 했다. 작성자를 클릭하면 작성자의 정보가 나오게 하는 것이다.



< user_select_info view >


  개인 정보 확인하는 것을 그대로 따왔다.



< urls 추가 >


  개인정보의 경우 로그인정보를 이용하여 정보를 가져오면 되지만 다른 사용자의 정보를 출력하기 위해서는 해당 사용자의 정보를 넘겨줘야한다. 그래서 나는 작성자를 넘겨 주기로 했다.



< 작성자 확인 테스트 >

  tfa 를 클릭해보았다.



< 다른 사용자 정보 확인 >


  다른 사용자의 정보를 확인 할 수 있었다.



=============================


* 추가할 기능 구현 (게시판)

- 댓글 기능

- 조회수 기능

- 게시글 삭제 기능


* 추가할 기능 구현 (인증)

- 소셜 인증


지난 일지에서의 나의 목표

1. 로그인 시 회원 정보를 이용해 화면에 표시. (My Page기능)

2. 소셜 인증(SNS, Email 등) 을 통한 회원가입 기능 추가. 


- 오늘 구현한 기능은 로그인 한 회원의 정보를 보여주는 My Page 기능을 구현하였다.


먼저 메뉴 바에서 My Page로 넘어가는 메뉴를 만들었다.


< 메뉴 생성 >


  url에 'login' 이름으로 입력을 넣어주었다. 다음으로 urls.py에 가서 해당 url을 만들어주었다. 


< urls.py >


  여기에 연결해준 view는 CBV를 사용하지 않았다. CBV를 사용하려고 노력했지만, User를 One To One 필드를 사용하여 Profile로 확장을 하여 쉽지 않았다. 그래서 내가 직접 view를 만들었다.



< userinfo vew >


  login_required 라는 데코를 사용하였다. 그러면 이제 이 view를 접근 할 때는 로그인이 필요하다. 물론, 로그인이 된 상태에서만 My Page 메뉴가 보이므로 로그인 한 상태에서 My Page에 들어오겠지만, url만을 가지고 들어올 가능성이 있기 때문에 데코를 사용하였다.


  프로필 사진의 경우 없을 수도 있기 때문에 if 문으로 처리해주었다.


  마지막으로 이에 연결될 템플릿을 만들어주었다.


< mypage.html >


  view에서 context로 넘겨받은 값들을 화면에 넣어주었다. 그리고 프로필 사진이 존재하지 않는다면 기본 이미지를 넣어주게 만들었다.



< 완성된 모습 >


  마지막까지 구현된 모습이다. 원하는 대로 원하는 정보가 출력되었다.


다음 나의 목표.

1. 소셜 인증(SNS, Email 등) 을 통한 회원가입 기능 추가. 




지난 일지에서의 나의 목표

1. 회원 정보 구체화

2. 로그인 시 회원 정보를 이용해 화면에 표시.

3. 소셜 인증(SNS, Email 등) 을 통한 회원가입 기능 추가. 


  오늘은 회원 정보를 구체화하고, 개인적인 목표로 생일을 입력할 때 달력에서 날짜를 선택해서 입력하는 기능을 추가하기로 했다.


  Widget 기능


  Widget 기능을 구현하기 위해 굉장히 해메었다. 찾았던 많은 방법 중 간단한 방법으로 구현하였다.


< WIdget 추가 >


  DateInput의 타입을 설정한 클래스를 widget에 넣어준다.


  여기서도 문제가 있었는데, 다른 컴퓨터에서 내가 개발했을 때는 위의 방법으로 위젯이 되었는데 다른 노트북에서 테스트 해보니 달력이 안생기는 것이었다. 문제가 무엇인지 한참 검색했더니, IE와 FF에서는 안되는 경우가 있다는 것을 보았다. FireFox에서도 되는 것을 확인했었는데 버전이 달랐던 것으로 받아들였다.


  그리하여 구글 크롬으로 테스트 하였더니 달력 기능이 되는 것을 확인 할 수 있었다.


< Widget 기능 >


  FF와 IE에서 어떤 문제로 안되는 지는 정확히 파악하지 못했지만, 이는 더 조사해보아야할 점이다.



  두 번째는 프로필 정보를 구체화 시켰다.


< 프로필 정보 >


  여기서 해커의 레벨을 등급으로 만들어 두고 이를 튜플로 선택할 수 있도록 만들었다. 이를 관리자 페이지에서 확인해보면 다음과 같다.


< 프로필 확인 >


  원하는 방식으로 구현 된 것을 확인하였다.


  이제 다음으로 회원가입 기능에 설정한 내용을 입력하게 하는 것이다.



< 필드 추가 >


  이는 기존의 방법대로 fields에 입력받을 폼을 추가하여 구현하였다.



< 회원 가입 화면 >


  회원 가입 화면은 위와 같다. 아직 디자인은 없어서 모양이 이상하지만 개발을 우선으로 하고 나중에 디자인 할 계획이다.


  회원 가입 테스트를 해본다!


< 회원 가입 테스트 >


  회원 가입 결과 성공적으로 회원가입이 되었다.



  이제 추가적으로 이렇게 입력받은 정보들을 확인할 수 있는 기능을 만들 것이다. 이를 위해 왼쪽 사이드 바에 mypage 란을 만든다.



< mypage 목록 추가 >




< 추가된 My Page >


  My Page에서 회원 프로필 정보를 확인하는 기능을 추가해야한다.!!



다음 나의 목표.

1. 로그인 시 회원 정보를 이용해 화면에 표시. (My Page기능)

2. 소셜 인증(SNS, Email 등) 을 통한 회원가입 기능 추가. 



'Web > Django Project' 카테고리의 다른 글

Code1018 Project (4) - 게시판 기능  (0) 2018.08.13
Code1018 Project (3) - mypage 기능  (0) 2018.08.07
Code1018 Project (1) - User 모델 확장  (0) 2018.08.02
Simple SignUp  (1) 2018.07.25
Simple Login/Logout  (0) 2018.07.24


  Python을 이용해서 웹 서버를 구축 프로젝트를 시작한다!


계획은 다음과 같다.

1. 인증부분 구현 (로그인,로그아웃 및 회원 관련)

2. Blog App 개발

3. Board App ( 게시판(질문게시판) ) 개발

4. Tools App ( 자료실 ) 개발


기본 Auth App을 사용하여 로그인 로그아웃 기능을 구현하였다. 이 기능은 인터넷에 많은 자료가 있어서 만들기 쉬웠다.


< 메인 페이지 >


  메인 페이지에서 왼쪽 사이드 바에는 앞으로 만들 목록들을 나열해 두었다. 그리고 로그인이 되었는지를 쉽게 알기 위해 메인에서는 로그인이 되었는지 안되었는지를 표시해준다.



< 로그인 화면 >


  위 처럼 로그인을 하게 되면 아래와 같은 메인 페이지로 바뀐다.



< 로그인 된 모습 >


  로그인 된 아이디를 가지고 간단한 인사를 해준다. 그리고 왼쪽 사이드 바에서 로그인, 회원 가입 목록이 사라지고 로그 아웃 버튼이 나오게 만들어 주었다.



  추가적인 욕심은 바로 이 User 모델을 확장하는 것이었다. 기본 User 모델을 이용해서는 내가 원하는 정보를 넣을 수 없었다. 예를 들어 회원 가입할 때 취미, 사는 위치, 생일 등 다양한 정보를 원할 수 있는데 기본 모델을 사용하기 때문에 확장하기 어려웠다.


  조사해본 바로는 User 모델을 확장하는 방법은 여러가지가 있었다. User 모델 차원에서 전부 뜯어 고치는 방법도 있었는데 나는 User 모델에서 One To One Field를 사용하여 회원 정보를 추가하기로 했다.


  이 방법은 정말 쉽고 인터넷에 찾아보면 쉽게 찾을 수 있다.


< OneToOneField를 이용한 확장 >


  여기까지는 쉬울 수 있으나 문제가 있었다. 이렇게 확장하는 것은 편리하긴 하나 회원가입할 때 이 추가정보들을 어떻게 보여주느냐가 문제였다.


  나는 CreateView (class 기반의 뷰) 를 사용할 건데 여기에는 form 을 하나만 넣어줄 수 있었다. 그렇기에 회원가입할 때 내가 확장한 정보들을 입력할 수 가 없었다.


  물론, class 기반 뷰를 사용하지 않고 직접 view를 작성하면 되긴 하지만 class 기반의 뷰를 이용하고 싶었다. 어떻게하면 두 form을 합칠지 고민해보았다.


( 이 고민을 하며 이 글을 보고 있는 사람이 있을 수 있으리라 생각한다. 나 또한 많이 고민하고 찾았다. )


  바로 MultiModelForm 을 이용하여 해결했다.

이를 사용하려면 아래의 라이브러리를 받아준다.



< django-betterforms 설치 >


  이 안에 있는 MultiModelForm을 사용하면 form 두개를 합칠 수 있다.


< form 합치기 >


  이렇게 합쳐주고 class 기반의 view에서 하나의 폼으로 입력해주면 된다.



< form 입력 >


  그러면 다음과 같이 성공할 수 있다.


< 확장 성공 >



  이제 테스트를 해보았다.



< 테스트 >


  그리고... 테스트 결과는 다음과 같았다.


< 테스트 결과 >


  가입 실패되었다. 에러 원인을 분석해보니 profile 폼에서 user id가 없다는 이야기였다.


  이유를 곰곰히 코드를 살펴보니 이해할 수 있었다.

나는 OneToOne으로 User와 Profile 을 연결하였다. Profile을 추가하기 위해서는 User가 필요한데(구체적으로 User.id) 회원가입할 때 동시에 입력을 넣기 때문에 안되었던 것이다.


  즉, User를 먼저 생성한 뒤, 내가 원하는 정보들인 Profile 정보를 저장할 때 생성한 User의 id를 연결해 줘야 한다는 것이다. 이를 위해서는 View에서 처리할 수 밖에 없었다.


< 회원 가입 처리 >


  동작 원리는 먼저 user 폼에서 들어온 정보들로 User를 생성하여 저장하고, 해당 User를 profile의 user와 연결해준다. ( 1대1 관계 )

  그 후 넘어온 Profile 정보들을 저장해준다.



< 테스트 >


  테스트 결과는 다음과 같다.


< 테스트 결과 >


  User 모델을 확장하는데 성공하였다.!!


다음 나의 목표.

1. 회원 정보 구체화

2. 로그인 시 회원 정보를 이용해 화면에 표시.

3. 소셜 인증(SNS, Email 등) 을 통한 회원가입 기능 추가. 

'Web > Django Project' 카테고리의 다른 글

Code1018 Project (3) - mypage 기능  (0) 2018.08.07
Code1018 Project (2) - 날짜선택 Widget 기능  (0) 2018.08.04
Simple SignUp  (1) 2018.07.25
Simple Login/Logout  (0) 2018.07.24
Django Tutorial - Form 만들기, 제네릭뷰 사용  (0) 2018.02.06


  지난 글에서 auth APP을 이용하여 로그인/로그아웃 기능을 구현하였다. 이번에는 회원가입 기능을 추가해 볼 것이다. 이를 위해 accounts APP을 만들어준다.



< accounts APP 생성 >


  이제 이 APP에 auth APP의 기능을 이용해 회원 가입 기능을 추가할 것이다. settings.py 를 수정해준다.


< settings.py 수정 >


  accounts APP을 생성한 후 settings.py 파일에서 임포트 APP 리스트에 추가해준다.



< urls.py 수정 >


  urls.py에 생성한 accounts 경로를 만들어주고 우리 APP의 urls을 include해준다. 위에서 아래로 url을 찾기 때문에 우리가 만든 APP의 urls.py를 검색한 뒤 여기에 없으면 auth APP의 urls.py에서 찾는 url을 찾을 것이다.



< accounts/urls.py >


  우리가 만든 APP의 urls.py에 회원 가입 경로를 설정해준다. views 파일에 SignUp 클래스를 만들어 줄 것이므로 위와 같이 view를 넣어준다.



< SignUp 클래스 생성 >


  이 클래스는 제네릭 CreateView이다. form은 auth APP에 있는 UserCreationForm을 사용할 것이고, template과 가입이 끝난 뒤 어디로 redirect 시킬지에 대한 정보를 입력한다. 



< signup.html >


  마지막으로 회원 가입하는 페이지! signup.html 템플릿을 만들어준다.



  이제 지금까지 구현한 회원가입 기능이 잘 동작하는지 확인해본다.



< Signup 페이지 >


  aacounts/signup/ 으로 접속하니 회원가입 페이지가 잘 나오는 것을 확인 할 수 있다. 이제 아이디와 비밀번호를 입력하여 회원가입한다.


< 회원 가입 >



  회원 가입 후 실제로 로그인 해본다.!



< 로그인 시도 >



< 로그인 성공 >


  우리가 회원 가입한 아이디로 로그인이 된 것을 확인 할 수 있었다.


  이로써 auth APP을 이용하여 회원가입 기능을 구현해 보았다.

Django 를 이용하여 웹 서버를 구축하는 프로젝트를 진행한다.


  우선 인증 관련 부분인 Login, Logout, 회원가입, 비밀번호 변경 등에 관한 기능을 구현할 것이다.


  제목을 Simple 이라 붙인 것은 단순하게 장고에 포함되어있는 auth app을 이용하여 구현해 볼 것이기 때문이다. 추후 커스터마이징을 하여 본 웹 프로젝트의 기능에 추가할 것이다.


< auth APP >



  settings.py 파일의 임포트하는 APP 리스트를 보면 'auth'라는 app이 있는 것을 볼 수 있다. 


  auth app 을 사용하기 위해 urls.py 에 url을 등록한다.


< urls.py >


  이름은 'accounts'로 url을 정해주었다. 어떤 이름이든 상관없다. 이 url로 auth.urls를 include하게 되면 아래와 같은 url 들이 추가적으로 등록된다.



< 추가되는 url 들 >


  다음으로 login을 할 페이지를 만들어야한다. 프로젝트 경로에서 templates 폴더를 만들어 준 후, 그 하위 디렉토리에 'registration' 이라는 이름으로 폴더를 만들어 준다. 그 아래에 login.html을 만들어준다.


  우리가 사용할 auth APP은 registration 폴더의 login.html 을 사용하기 때문에 우리가 이와 같은 경로와 이름으로 파일을 만들어 주는 것이다.


< login.html 파일 생성 >


  그 후 login.html 을 작성한다.


< login.html >


  login.html 을 보면 post 방식으로 내용을 전달한다. 여기서 form.as_p 는 우리가 입력해야할 대상들을 <p> 으로 감싸서 출력해준다. Login 버튼을 누르면 submit 기능을 하는데 post 방식으로 우리가 입력한 아이디와 비밀번호를 전달하는 기능을 한다.


  위의 템플릿을 찾아 갈 수 있도록 settings.py 에서 TEMPLATES 디렉토리를 지정해준다.



< settings.py 수정 >



  이 파일 맨 마지막에 login 했을 때, 어디로 redirect 시킬지에 대한 정보도 같이 적어준다.


< settings.py 수정 >


  login이 되었을 때, '/' 경로로 이동시킨다.



  지금 까지 만든 화면을 확인해 보겠다.



< 중간 확인 >


  사용자 아이디와 비밀번호를 입력하는 란이 나오고 login 버튼까지 잘 만들어 졌다.



  로그인이 성공했을 대 '/' 페이지로 이동하도록 했는데, 아직 '/' 페이지가 없다. 그러므로 지금 만들어 주도록 할 것이다.


< template 추가 >


  확장성 있게 개발하기 위하여 block content를 사용할 것이다. 다음은 base.html 이다.


< base.html >


  이제 base.html을 이용하여 home.html을 작성한다.


< home.html >


  home.html 내용을 보면 user.is_authenticated 라는 함수로 인증이 됬는지를 확인하고 있다. 인증이 되었다면 이름과 안녕 그리고 로그아웃 버튼을 출력해주고 인증이 되지 않았다면 로그인이 되지 않았으므로 로그인 할 수 있도록 링크를 달아주었다.



< login.html >


  base.html 을 이용하여 login.html도 수정하였다. 마지막으로 지금 만든 '/' 경로에 url을 설정해준다.


< urls.py >


  home.html을 보여준다. 여기서 url 이름을 home으로 정했으므로 로그인했을 때, 로그아웃 했을 때 리다이렉션 시켜줄 주소를 하드코딩 하지 말고 위의 이름으로 바꾸어준다.


< redirect url >



  이렇게 되면 완성이다. 지금 까지 만든 기능을 확인해볼 것이다.



< 로그인 화면 >


  로그인 화면에 기존에 만들었던 superuser로 로그인해보앗다.



< 로그인 된 화면 >


  root에게 인사를 하고 아래에 logout 링크가 있다. 해당 링크를 클릭하면 로그아웃이 된다.



< 로그아웃 된 모습 >


  로그아웃이 되면 위와 같이 로그인이 되지 않았다며 로그인 하는 링크를 보여준다.


  지금까지 Django에 내장되어있는 auth APP을 이용하여 간단한 login/logout 기능을 구현해 보았다.

+ Recent posts