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

- 조회수 조작 방지 기능



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

- 소셜 인증


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


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


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




  자료실 모델이다.


< 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 기능을 구현해 보았다.


지금 까지만든 설문지페이지에서 오늘은 form을 작성해 볼 것이다.

 HTML에서 form은 데이터를 전달 하는 기능을 한다.
우리는 설문지에서 설문 선택지를 선택하고 버튼을 클릭하면 선택한 선택지의 정보를 담아서 웹 페이지에 전달할 것이다.

이 내용은 DB에 저장될 것이므로, POST 방식으로 보내게 할 것이다.


(detail.html)


detail.html 템플릿은 question 객체를 받는다.
받은 question 객체에서 질문 내용인 question_text를 h1 태그로 찍어준다.

그리고 에러메시지가 있으면 해당 에러 내용을 출력해준다.

그 다음 부터는 form 태그이다.
그런데 중간에 csrf 토큰이 보일 것이다. 우리는 form 을 사용하여 데이터를 전달할 것이기 때문에 CSRF 공격에 대해 생각하고 있어야한다. 장고에서 대신 CSRF 공격에 대해 예방하는 기능이 있는데
{% csrf_token %} 만 작성하면 된다. (나중에도 form 문에는 이 문구를 적어넣어야한다. )
해당 question객체에서 선택지들을 전부 가져온 후 for 문을 돌면서 radio 버튼과 선택지 내용을 출력한다.

웹페이지를 실행시켜서 직접 확인해보자!



(form 페이지)


질문 내용이 위에 찍혀있고 선택지들이 버튼과 함께 나열되어있는 것을 볼 수 있다.

위에 form 코드를 다시 보면 url vote로 이동하라고 action에 나와있다.

url vote는 우리가 작성한 polls/urls.py를 확인하면 알 수 있다.


(vote)


vote이름을 가진 주소패턴에 해당 question.id가 조합이 되면 어떤 주소가 된다.
보면 views.vote를 실행하게 되어있다.

그렇다면 views.vote를 작성해주자!


(views.vote)


우리는 question_id를 주소에서 전달받게 된다. 전달 받은 question_id를 pk로 사용하여 해당 질문 객체를 가져온다.
그 후 선택된 선택지를 가져오는데 request객체 안에 POST에 담겨있다. 우리가 POST로 전달했기 때문이다. POST 속에 choice=### 이런식으로 담겨온다. choice변수에 담긴 값을 pk로 선택된 질문을 가져온다. 그 후 선택된 질문객체에서 투표수를 1 증가시키고 저장한다.
그리고 Redirect한다. reverse를 사용해서 url 주소를 만든다.
polls 이름 영역의 urls.py에 정의 되어있는 results 이름의 주소 패턴을 가져오고 인자로 question.id를 조합하여 특정 url을 만드는 것이다. 그 주소로 리다이렉트한다.

그렇다면 처리된 결과를 확인하는 results의 화면도 만들어보자.


(views.results)


위에서 리다이렉트된 주소는 views.results를 호출한다. polls/urls.py를 확인하면 알 수 있다.
이 뷰에서는 질문 객체를 가져오고 이 질문 객체를 가지고 polls/results.html 템플릿을 보여준다.

보여주는 results.html 템플릿은 아래와 같다.


(results.html)


질문 객체에서 각각의 선택 내용과 투표수를 출력하는 템플릿이다.

실행해서 확인해보자.



(실행 확인)


확인해보니 잘 된다!

질문 객체를 가져오고, 질문 객체를 가지고 템플릿으로 전달하고 등등
어떻게 보면 이것 또한 루틴한 작업이다.
그래서 이번에는 제네릭 뷰를 이용해서 위의 페이지를 똑같이 만들어 볼 것이다.

제네릭 뷰에는 리스트뷰와 디테일뷰가 있다.
리스트뷰는 말 그대로 리스트들을 보여주는데 사용하고
디테일뷰는 우리가 detail view를 만들었던거와 같다.

먼저 제네릭뷰를 사용하기 전에 polls/urls.py를 수정해줘야한다.


(polls/urls.py)


제네릭뷰에서는 pk로 전달 받기 때문에 pk로 바꾸어 주었다.
그리고 호출하는 것이 각각의 뷰에서 as_view() 함수를 호출한다.
우리는 views에 위에서 사용한 클래스를 만들어줘야한다.

이어서 view를 수정해 줄 것이다. 제네릭 뷰를 이용해 수정한 코드는 아래와 같다.


(제네릭 뷰)


각각의 클래스를 만들었다.
template_name은 우리가 사용할 템플릿 위치를 알려준다.
그리고 model은 어떤 모델이 적용될 것인지 지정해주는 것이다.
DetailView의 경우 question 변수가 자동으로 제공된다. 그러나 ListView의 경우 자동 생성된 컨텍스트변수는 question_list이기 때문에 우리가 템플릿에서 사용했던 변수 이름으로 맞춰주기 위해 context_object_name의 변수로 지정해주었다.

ListView에서 get_queryset을 가지고 쿼리를 날리는데 우리는 최근 5개 글을 볼것이므로 해당 함수를 덮어쓴 것이다.

실행해서 웹페이지에서 똑같은 동작인지 확인해보자



(동작 확인)


같은 동작을 하는 것을 확인 할 수 있다.

(* 참조 - https://docs.djangoproject.com/ko/2.0/intro/tutorial04/)

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

Simple SignUp  (1) 2018.07.25
Simple Login/Logout  (0) 2018.07.24
Django Tutorial - Views ( Template와 연결 )  (0) 2018.02.01
Django Tutorial - 관리자 생성 및 페이지보기  (0) 2018.01.31
Django Tutorial - Model  (0) 2018.01.31

+ Recent posts