지금까지는 서버상의 작업을 AWS 의 웹 터미널을 통해서 해왔지만 AWS 웹 터미널은 연결도 자주 끊어지고 상당히

불편하다. 이번에는 다른 터미널 프로그램을 사용하여 작업하는 방법에 대해 알아본다.

 

1. 프라이빗 키

 웹 터미널 대신 일반 터미널에서 AWS 서버에 접속하려면 AWS 계정 프라이빗 키가 필요하다. 

 

AWS 라이트세일 홈페이지에서 계정(Account) 메뉴로 들어간다.

 

SSH keys 탭에서 Download 를 클릭하면 프라이빗 키 파일(.pem 파일)을 다운로드 받을 수 있다.  이 파일을

<프로젝트명>.pem 으로 이름을 바꾸어 로컬 개발환경의 venvs 디렉토리로 이동시킨다.

 

 

2. 터미널 프로그램

 터미널 프로그램은 다양하지만 여기서는 강좌대로 MobaXterm 을 사용하기로 한다.  개인적으로도 쓸만한 터미널

프로그램들을 찾아봤는데 MobaXterm 이 무료 터미널 프로그램중에서는 평가도 가장 좋은편이고 기능도 좋아보였다.

MobaXterm 다운로드 페이지에서 무료버전을 받아 설치하자. 

 

실행하면 위와 같은 화면이 보인다. Session 을 클릭하자.

 

종류는 SSH로 하고 Remote host 에 서버의 고정 ip를, Specify username 에 ubuntu를(인스턴스의 SSH 클라이언트

기본명이 ubuntu 로 되어있다), private key는 프라이빗 키 파일(mysite.pem)의 경로를 지정해준다. 그리고 ok를 누르면

이제 서버에 접속하기 위한 설정이 완료되었다.

 

이제 MobaXterm 에서 서버에 접속할 수 있다.

 

MobaXterm 은 기본적으로 SFTP 기능을 내장하고있어 원격접속한 서버와 파일을 주고받기 위해 별도의 프로그램을

사용할 필요가 없다. 좌측의 SFTP 탭에서 드래그앤 드롭만으로 서버와 파일을 주고받을 수 있다.

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#33 Gunicorn  (0) 2021.10.15
#32 WSGI  (0) 2021.10.15
#30 settings.py 분리  (0) 2021.10.14
#29 AWS  (0) 2021.10.14
#28 검색과 정렬  (0) 2021.10.12

1. 로컬환경, 서버환경의 분리

 지난 글에서 AWS 라이트세일을 사용하여 pybo 서버를 오픈하기 위해 config/settings.py 의 ALLOWED_HOSTS 를

수정하였다. 그런데 이렇게 하면 로컬 개발환경에서 서버를 구동할 수 없는 문제가 발생한다. 그리고 ALLOWED_HOSTS

외에도 로컬 개발환경과 서버환경에서의 설정이 달라야하는 부분도 분명 존재할 것이다.  이런 문제를 해결하려면 

로컬환경과 서버환경에서의 설정을 달리 적용시킬 수 있어야한다.

 

 

2. settings.py 분리

 settings.py 를 분리하는 작업은 views.py 의 분리작업과 유사하게 진행된다. 

 

먼저 config 디렉토리에 settings 디렉토리를 생성한 뒤 기존 settings.py 를 base.py 로 파일명을 변경하여 settings

디렉토리로 옮긴다.  그 후 파일이 한층 더 디렉토리 내부로 이동했으니 BASE_DIR 끝에 .parent를 한번 더 붙여준다.

 

로컬 환경용 설정파일 local.py 를 생성하여 base.py 를 import 해주고 ALLOWED_HOSTS 를 빈 리스트로 설정한다.

 

서버 환경용 설정파일 prod.py 를 생성하여 base.py 를 import 해주고 ALLOWED_HOSTS 에 AWS 라이트세일

인스턴스의 고정 IP를 넣어준다.

 

이제 로컬측에서 python manage.py runserver --setings=config.settings.local 을 실행하면 서버가 정상적으로

구동되는 것을 확인할 수 있다.  --settings 는 어느파일을 settings.py 로 인식할지 지정하는 옵션이다.

 

 

3. alisas 를 사용한 서버 설정 자동화

sh 파일을 사용한 자동화는 sh 파일의 경로를 찾아가 실행해야하는 불편함이 있다.  이를 보다 편하게 바꿔보자.

 

cd ~
vi .bashrc

 

위와 같이 홈 디렉토리로 이동(cd ~)한 뒤 .bashrc 파일을 vi 로 열어 맨 아랫줄에 mysite 라는 alias 를 추가해준다.

DJANGO_SETTINGS_MODULE 는 서버 실행시 --settings=config.settings.local 옵션을 대신해주는 환경변수이다.

mysite='<실행할 명령어>' 에서 = 좌우로 띄어쓰기를 넣지 않도록 해야한다. 

 

.bashrc 파일을 저장한 뒤 실행시키는 것으로 수정사항을 반영해주고나서 alias 명령어를 실행시키면 mysite 가 alias

목록에 추가된 것을 확인할 수 있다. 

 

이제 어디서든 mysite 명령어로 서버 환경에서의 설정파일을 지정하고 프로젝트 디렉토리로 이동하여 가상환경에

진입하는 작업을 자동으로 실행할 수 있다.

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#32 WSGI  (0) 2021.10.15
#31 터미널 접속  (0) 2021.10.14
#29 AWS  (0) 2021.10.14
#28 검색과 정렬  (0) 2021.10.12
#27 마크다운(Markdown)  (0) 2021.10.11

 이제 pybo가 간단하지만 어느정도의 기능을 갖춘 웹페이지가 되었으니 다른 사용자들도 ip만 알고있다면 접속

가능하도록 서버를 구축해야한다.  직접 서버를 구축하는 방법도 있지만 개인용 pc로는 성능에도 한계가있고 방법도

쉽지 않기 때문에 여기서는 AWS(Amazone Web Services) 의 라이트세일 서비스를 사용하여 보다 쉽고 저렴하게

pybo를 배포해본다.

 

1. AWS 가입

 먼저 AWS 공식 홈페이지에서 계정을 만들어야한다. 

 

홈페이지에서 계정 생성을 누르면 위와 같은 화면을 볼 수 있다.  이메일 주소와 암호, 계정이름을 입력하고 진행한다.

 

사용 타입은 개인으로, 전체이름에는 서버의 이름을, 전화번호에는 국가번호와 휴대폰번호를 입력한다. 주소는 한국을

기준으로 국가는 대한민국, 첫 번째 칸에는 건물의 주소를, 두 번째 칸에는 동/층/호수 를 입력하고 시에는 ㅇㅇ구,

ㅇㅇ군, ㅇㅇ시 등의 정보를,  시, 도 또는 리전에는 대한민국을 입력해주면 된다.  juso.go.kr 등의 사이트에서 주소를

검색한 뒤 영문보기를 하면 쉽게 입력할 수 있다.  우편번호까지 입력하고 다음으로 진행한다.

 

결제정보를 입력하는 화면이 나온다. 2021년 10월기준 결제정보 확인을 위해 100원이 빠져나가는데 짧은시간내에

다시 입금되기 때문에 걱정할 필요는 없다.

 

이후부터는 카드와 전화번호의 인증절차만 거치면 AWS 코드가 발송되고 이를 입력하면 성공적으로 계정이 생성된다.

지원 플랜을 선택하라고 하는 창이 뜨면 무료인 기본 플랜을 선택하면 된다.  이후 콘솔에 로그인 버튼을 클릭하여

생성한 계정으로 로그인해준다.

 

 

2. AWS 라이트세일 인스턴스 생성3

로그인을 마치고 AWS 라이트세일 공식 홈페이지에 접속하면 위와 같은 화면이 뜬다.  필자의 경우 이미 인스턴스를

만들어두었기 때문에 Ubuntu-1 이라는 인스턴스가 존재하지만 처음 가입한 상태에서는 바로 인스턴스 생성 화면이

보일 것이다. 

 

플랫폼으로는 Linux/Unix 환경과 Windows 환경을 모두 지원한다.  여기서는 Linus 환경을 사용하기로 한다.

blueprint는 앱과 OS를 결합시킨 버전도 있고 OS만을 지원하는 버전도 있는데, 우린 이미 앱으로 django 를

사용하고있으니 OS Only 에서 개인프로젝트에 사용하기에 가장 무난한 Linux 환경인 우분투를 선택한다.

 

마지막으로 인스턴스 플랜으로 첫 3달간 무료지원을 해주는 플랜을 선택한다.  5달러, 10달러 플랜도 3달 무료를

지원하지만 여기서는 3.5달러의 가장 저렴한 플랜을 선택하기로 한다.

 

인스턴스를 생성하고나면 Running 이라고 표시된 위치에 Pending 또는 대기 중이라는 메시지가 떠있을 것이다.  

조금 기다리면 Running 또는 실행 중이라는 메시지로 바뀌면서 서버가 실행된다.

 

 

3. 서버시간 설정

AWS 콘솔에 로그인한 후 AWS 라이트세일 홈페이지에 접속해서 위의 동그라미친 셸 아이콘을 클릭하자.

 

그러면 우분투의 터미널과 같은 창이 열린다.  여기서 우리가 생성한 서버를 조작할 수 있다.

 

처음 서버의 시간은 UTC 기준으로 맞춰져있다.  한국 시간에 맞게 조정하려면 다음 명령어를 실행하자.

sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

Asia/Seoul 타임존의 심볼릭 링크를 생성하여 /etc/localtime 을 덮어씌우는 리눅스 명령어이다. 실행하고나서 다시

date 명령어를 실행하면 이제 정상적으로 한국시간이 표시되는 것을 확인할 수 있다.

 

 

4. 파이썬 설치 확인

 장고를 사용하기 위해서는 파이썬이 필요하다.  서버에 파이썬이 설치되어있는지 확인하자.

 

셸에서 python 을 실행하면 찾을 수 없다는 메시지가 나오지만 python3 을 찾아보라는 메시지가 떠서 python3 을 

입력해보니 정상적으로 설치가 되어있는 것을 확인할 수 있다.  설치된 것을 확인했으면 exit() 로 파이썬 셸을 종료한다.

 

 

5. 가상환경 설치

처음 프로젝트를 시작했을 때 처럼 가상환경을 구성해보자. 먼저 다음 명령어를 호출하여 우분투의 패키지들을

최신버전으로 업데이트하자.

 

sudo apt update

 

 

 

가상환경의 설치를 위해 python3-venv 패키지를 설치하자.

 

sudo apt install python3-venv

 

필자의 경우 이미 설치가 끝나있기 때문에 변경사항이 없다.  중간에 선택화면이 나타나면 y(yes) 를 선택해주면 된다.

 

 

홈 디렉토리(~) 에 파이보가 위치할 projects 디렉토리와 가상환경을 생성할 venvs 디렉토리를 생성한다.

 

mkdir projects
mkdir venvs

 

정상적으로 두 디렉토리가 만들어진 것을 볼 수 있다.

 

 

프로젝트 초반에 했던 것 처럼 다음 명령어들을 실행하여 venvs 디렉토리로 이동한 뒤 가상환경을 생성한다.

 

cd venvs
python3 -m venv mysite

 

 

 

다음 명령어들을 수행하여 mysite/bin 으로 이동한 뒤 activate 를 실행해준다.

 

cd mysite/bin
. activate

 

어디서든 가상환경을 벗어나려면 deactivate 를 실행해주면 된다.  이후의 작업은 가상환경 내에서 이뤄진다.

 

 

6. wheel 패키지, django, markdow 패키지 설치

 로컬 환경에서는 문제가 없었지만 서버 환경에서는 pip 로 파이보 관련 패키지들을 설치할 때 wheel 패키지 관련

오류가 발생할 수 있다고 한다.  다음 명령어들을 실행하여 먼저 wheel 패키지를 설치한 뒤 django 와 markdown

패키지를 설치해준다. 

 

pip install wheel
pip install django==<버전>
pip install markdown

 django 의 경우 ==으로 버전을 명시하여 설치한다.  필자의 경우 로컬에서 사용했던 버전인 3.2.6 버전을 쓰기 위해

pip install django==3.2.6 과 같이 실행하였다.

 

 

7. Pybo 설치

 이제 드디어 우리가 만들었던 Pybo를 설치할 차례이다.  지금까지 작업한 파이보 프로젝트의 파일들은

git 원격 저장소에 push 한 뒤 서버에서 clone 하는 것으로 손쉽게 가져올 수 있다.

 

 

cd ~/projects
git clone "https://github.com/<유저명>/<레포지토리명>.git <프로젝트이름>

위와 같이 push 해둔 pybo 프로젝트의 레포지토리에서 code 버튼을 클릭, url을 확인한 뒤 projects 디렉토리에서

git clone 명령어를 수행해주면 레포지토리에 저장된 프로젝트를 그대로 가져온다.

 

원격저장소에 올려둔 파일들이 모두 서버에 복사되었다.

 

 

8. 데이터베이스 생성

 하지만 아직 서버를 정상적으로 구동할 수는 없는 상태이다.  우리가 간이 db로 사용했던 db.sqlite3 는 당연하게도

원격저장소에 포함되어있지 않기 때문에 먼저 마이그레이션을 실행해줘야 한다. 

 

python manage.py makemigrations
python manage.py migrate

 

pybo/migrations 디렉토리에 makemigration 으로 만들어진 파일들이 모두 들어있다면 makemigrations 는 수행할 필요

없이 migrate 명령어만을 수행해도 마이그레이션이 완료되고 db.sqlite3 이 생성된 것을 확인할 수 있을 것이다.

데이터베이스 외에도 서버의 SECRET_KEY 값을 분리해둔 파일과 같은 원격저장소에 공유해선 안되는 종류의 파일들

또한 서버에는 존재하지 않는 상태이다. 이들 또한 서버에 전송하여 서버가 정상적으로 구동할 수 있는 환경을 조성하자.

 

 

9. 고정 IP 생성

 이제 pybo 서버는 구동 가능한 상태가 되었지만 다른 사용자들이 접속하기 위해서는 고정 ip를 발행해야한다. 

 

AWS 라이트세일 홈페이지에 접속해서 네트워킹 탭으로 들어가면 Create static IP 로 고정 IP를 생성할 수 있다.

인스턴스 선택 창에서 우리가 만들었던 인스턴스를 선택해주고 생성 버튼만 눌러주면 간단히 만들어진다.

 

 

만들어진 고정 IP에 들어가면 IP 주소를 확인할 수 있다. 이제 이 IP를 통해 서버에 접속할 수 있다.

 

 

10. 방화벽 설정

 pybo 서버의 포트번호는 8000 번이기 때문에 방화벽 규칙을 설정하여 8000번 포트를 개방해야한다.

 

 

AWS 라이트세일에서 만들어둔 인스턴스에 들어가 네트워킹 탭을 보면 위와 같이 방화벽 규칙을 추가할 수 있다.

 

포트번호에 8000 을 입력하고 생성하자.

 

이제 장고 서버를 8000 포트를 개방하도록 실행하면 외부사용자도 접속이 가능하다.

 

 

11. ALLOWED_HOSTS 추가

 그런데 서버를 실행하고 브라우저에서 고정 ip로 접속하면 DisallowedHosts 에러가 발생할 것이다. 이는 해당 웹서버를 

구동할 수 있는 호스트로 현재 ip를 등록해두지 않았기 때문에 생기는 문제이다. 

 

로컬 프로젝트에서 config/settings.py 를 위와 같이 수정한 뒤 commit 하고 원격 저장소에 push 한다.

ALLOWED_HOSTS 리스트에 발급받은 서버의 고정 ip를 문자열 형태로 넣어주면 된다. 

 

그리고 다시 서버쪽에서 git pull 명령을 실행하여 원격저장소의 변경사항을 서버에 반영해준다. 필자의 경우 이미

업데이트가 진행되어있기 때문에 변경사항이 없지만 변경사항이 있을 경우 정상적으로 반영해줄 것이다.

 

 

12. 서버 구동

다시한번 8000 포트를 개방하여 서버를 구동한다.

 

이제 정말로 고정 ip만 알고있다면 다른 사용자도 pybo에 접속할 수 있게 되었다.

 

 

13. AWS 라이트세일 사용종료

 2021년 10월 기준으로 AWS 라이트세일의 인스턴스중 3.5달러, 5달러, 10달러 플랜은 첫 3개월간 무료지원을 해준다.

기간이 지나고도 의도하지 않은 요금이 발생하지 않도록 사용을 중지하려면 인스턴스와 고정 IP를 삭제해야한다.

 

 

인스턴스의 경우 AWS 라이트세일 홈페이지에서 인스턴스 메뉴에서 삭제를 클릭하면 삭제 가능하다.

 

고정 IP의 경우 네트워킹 탭에서 마찬가지의 방법으로 삭제할 수 있다.

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#31 터미널 접속  (0) 2021.10.14
#30 settings.py 분리  (0) 2021.10.14
#28 검색과 정렬  (0) 2021.10.12
#27 마크다운(Markdown)  (0) 2021.10.11
#26 앵커  (0) 2021.10.11

이번에는 Pybo의 index 페이지에 검색기능과 정렬기능을 추가해본다.

 

1. 검색창 추가

검색창은 페이징 영역 아래쪽에 중간부분에 오도록 만들 것이다.  question_list.html 의 페이징 영역 아래부분을

위와 같이 수정해준다.

 

 

2. searchForm, 스크립트 코드 작성

그리고 검색영역 아래부분에 검색창에서 입력받은 내용을 뷰 함수에 전달하기 위한 폼을 만들어준다.

hidden 속성으로 검색어(kw)와 페이지번호(page) 데이터를 받아오는 폼이다.

 

지금까지 페이지번호를 직접 url로 요청했던 링크들도 수정해준다. 

 

<a class="page-link" href="?page={{ <페이지번호> }}">{{ <페이지번호> }}</a>

이와 같은 형태였던 링크들을

 

<a class="page-link" data-page="{{ <페이지번호> }}" href="#">{{ <페이지번호> }}</a>

이와 같이 변경한 것이다.

 

게시글, 답글, 댓글 삭제 기능을 구현할 때도 href 값을 #으로 하고 data-XXX 의 형태로 값을 저장만 해두었던 것을

기억할 것이다.  이번에도 그 때와 마찬가지로 스크립트 코드를 통해 이를 처리해야한다.  삭제 기능을 구현할 때와

마찬가지로 스크립트 블록 내에 자바스크립트 코드를 작성해준다. 

 

page-link 클래스의 링크가 클릭될 경우 data-page 로 저장된 페이지번호를 page 변수에 세팅해준 뒤 searchForm 을

제출한다.  searchForm 은 kw에는 값이 없으니 빈 문자열이, page에는 자바스크립트 코드에서 설정된 페이지번호가

들어간 채로 GET 방식으로 제출되어 뷰 함수에서 처리된다.

 

id가 btn_search 인 버튼이 클릭될 경우 kw클래스의 값을 가져와서 kw 변수에 세팅, page 변수는 모든 페이지에 대해

검색해야 하기 때문에 1로 세팅한 뒤 searchForm 을 제출한다.  page-link 때와 마찬가지로 searchForm 은 이 값들을

입력값으로 받아 GET 방식으로 제출하여 뷰 함수에서 이를 처리한다.

 

 

3. 뷰 함수 수정

이제 pybo/views 디렉토리의 base_views.py 를 수정하여 실제로 searchForm 을 처리해야한다.

 

먼저 django.db.models 의 Q 함수를 import 한다.  이 함수는 게시글 리스트에서 검색조건에 맞는 글만을

필터링하기 위해 사용된다.

 

request에서 키워드(kw) 값을 가져온다.

 

위와 같이 코드를 작성하여 question_list 의 항목들을 필터링한다.  각 게시글의 subject(제목), content(내용),

author.username(글쓴이 이름), answer.author.username(답글 글쓴이들의 이름) 에 kw가 포함되어있는 경우만을

필터링한 것이다.  icontains 대신 contains 를 사용할 경우 대소문자를 구분하여 검색결과를 반영할 수 있다.

 

마지막으로 index 페이지를 렌더링 할 때 넘겨줄 context 에 kw 와 page 도 추가한다.  이렇게 하면 검색 후

index 페이지에서도 내가 검색한 검색어가 그대로 검색창의 텍스트필드에 남아있으며 검색을 위해 페이지를 1로

세팅한 것도 반영된다.

 

 

 

검색 결과가 정상적으로 반영되는 것을 볼 수 있다.

 

 

4. 정렬 조건 선택창 추가

이제 정렬기능을 구현할 차례다.  먼저 정렬 기준은 최신순(작성된 날짜가 최신일수록 위에), 추천순(추천 수가 많을수록

위에), 인기순(답글 수가 많을수록 위에) 세 가지로 구현할 것이다.

 

검색창의 텍스트필드 좌측에 위와같이 선택박스를 생성한다.  so 값으로 설정된 선택지가 선택박스에 표시된다.

 

정렬 기능 또한 searchForm 에서 처리하도록 할 것이다.  정렬 조건인 so를 입력값으로 받아오도록 한다.

 

정렬 처리를 위한 스크립트 코드도 추가해준다. 정렬 조건인 so 값이 변경된 경우 so는 변경된 so값으로,

page는 1로 설정하여 searchForm 을 제출한다.

 

django.db.models 에서 이번에는 Count 함수를 import 한다.

 

request 에서 정렬 기준 so 값을 받아와 그에따라 정렬을 수행한다.  annotate 함수와 Count 함수를 사용하여 추천자

수와 답글 갯수를 구할 수 있다.  만약 추천자 수나 답글 갯수가 같다면 작성 날짜가 최신일수록 위에 오도록 하여

정렬한다.

 

페이지가 다시 렌더링된 후에도 선택한 정렬조건이 남아있도록 하기 위해서 so 값도 context 에 추가한다.

 

 

 

이제 정렬 기능이 정상적으로 동작하는 것을 확인할 수 있다. 

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#30 settings.py 분리  (0) 2021.10.14
#29 AWS  (0) 2021.10.14
#27 마크다운(Markdown)  (0) 2021.10.11
#26 앵커  (0) 2021.10.11
#25 추천 기능  (0) 2021.10.10

 일반적인 블로그 등에서 글을 작성할 때 텍스트를 진하게 표시하거나 하이퍼링크를 추가하거나 글머리 기호를 추가하는 등 다양한 시각효과를 줄 수 있다.  물론 마크업(Markup) 언어인 HTML을 이용해서도 가능한 일이지만 마크다운

이라는 마크업 언어의 경량버전 언어를 사용하면 보다 간단하게 텍스트를 원하는 형태로 표현할 수 있다.  블로그 외에도 Github 와 같은 많은 웹사이트들이 마크다운 문법을 사용한 글쓰기를 지원한다.

 

1. 마크다운 문법

 Pybo에 마크다운을 통한 글쓰기 기능을 추가하기에 앞서 마크다운 문법에 대해 간단하게 알아보자.

 

 ① 리스트

   말그대로 어떤 항목들의 목록을 나타내기 위해 사용된다.

* 항목 1
* 항목 2
* 항목 3

  이와 같은 방식으로 작성할 수 있으며

 

  실제 웹페이지에선 위와 같은 형태로 표시된다.

 

 

 ② 순서 리스트

   리스트와 동일하지만 항목들의 순서를 나타낼 필요가 있는 경우 사용한다.

1. 항목 1
1. 항목 2
1. 항목 3

  이와 같은 방식으로 작성할 수 있으며

 

  실제 웹페이지에선 위와 같은 형태로 표시된다.

 

 

 ③ 강조

   특정 텍스트를 강조표시하기 위해 사용한다.

일반텍스트 **강조할 텍스트** 일반텍스트

  이와 같은 방식으로 작성할 수 있으며

 

  실제 웹페이지에선 위와 같은 형태로 표시된다.

 

 

 ④ 링크

   텍스트에 하이퍼링크를 추가할 때 사용한다. 

[파이썬 홈페이지](http://www.python.org)

  이와 같은 방식으로 작성할 수 있으며

 

  실제 웹페이지에선 위와 같은 형태로 표시된다.

 

 

 ⑤ 소스코드

   코드블럭을 만들어 그 안에 소스코드를 표현할 때 사용한다.

```
def python():
	print('HelloPython')
```

  이와 같은 방식으로 작성할 수 있으며

 

  실제 웹페이지에선 위와 같은 형태로 표시된다.

 

 

 ⑥ 인용

   인용을 표시할 떄 사용한다.

> 인용할 내용

  이와 같은 방식으로 작성할 수 있으며

 

  실제 웹페이지에선 위와 같은 형태로 표시된다.

 

 마크다운의 문법은 이 외에도 다양하지만 더 자세한 내용에 대해서는 마크다운 문법 공식문서를 참조하자.

 

 

2. 마크다운 설치

 마크다운의 문법에 대해 간단히 알아보았으니 이제 Pybo에 마크다운 기능을 적용할 차례이다. 먼저 터미널에서

아래 명령어를 실행하여 마크다운 모듈을 설치하자.

 

pip install markdown

 

성공적으로 설치된 것을 확인할 수 있다.

 

 

3. 마크다운 필터 등록

 마크다운으로 작성한 문서를 HTML 문서로 변환하기 위해서는 템플릿에서 사용할 마크다운 필터를 작성해야한다.

 

이전 페이징의 구현을 위해 만들었던 pybo_filter.py 에서 markdown 모듈과 django.utils.safestring 의 mark_safe 함수를

import 한다.  그리고 mark 필터를 위와같이 작성하여 등록한다.  extensions 에는 마크다운 문법으로 글을 작성할 때

개행 시 공백문자를 두번 입력할 필요가 없도록 하기 위해 nl2br을, 마크다운 코드 표현을 위해 fenced_code를 넣어준다.

mark다운 모듈과 mark_safe 함수를 사용하여 입력받은 마크다운 코드를 해석하고 이를 HTML 코드로 변환한다.

 

question_detail.html 의 두 번째 라인에서 필터를 로드해준다.

 

그리고 아래쪽의 게시글 내용을 표시하는 코드를 위와 같이 수정하여 mark 필터를 적용하여 출력되도록 한다.

 

답글에도 마찬가지로 적용해준다.

 

 

4. 마크다운 적용 확인

이제 마크다운 필터 적용이 정상적으로 이루어졌는지 확인하기 위해 테스트를 해본다.

 

 

다른 것들은 잘 적용이 되지만 코드블럭과 인용 부분은 스타일이 적용되지 않아 적용된것이 확실히 보이지 않는 것을

볼 수 있다.

 

static 디렉토리의 style.css 에서 pre 태그와 blockquote 태그에 대한 스타일을 수정해준다.

 

이제 코드블럭과 인용 부분이 적용된 것을 쉽게 확인할 수 있다.

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#29 AWS  (0) 2021.10.14
#28 검색과 정렬  (0) 2021.10.12
#26 앵커  (0) 2021.10.11
#25 추천 기능  (0) 2021.10.10
#24 View 파일 분리하기  (0) 2021.10.10

1. 앵커(Anchor)

 현재 Pybo는 댓글이나 답글을 작성/수정하고나면 게시글 상세페이지로 리다이렉트되며 페이지 최상단으로 이동하기

때문에 자신이 작성한 답변을 확인하기 위해 스크롤을 내려야 한다.  Ajax 와 같은 비동기 통신기술을 사용하면 페이지의

리로드 자체가 발생하지 않기 때문에 자동으로 해결될 일이지만 여기서는 앵커(Anchor)를 사용하여 보다 쉽게 해결하려

한다. 하이퍼링크를 추가할때 사용햇던 <a> 태그가 바로 앵커 태그이다.  앵커 태그를 통해 다른 웹 페이지의 하이퍼

링크나 웹페이지 내 특정 부분으로 이동할 수 있다. 

 

2. 답글 앵커 추가

 특정 답글로의 이동을 위해서는 먼저 답글의 위치에 앵커태그를 추가해둬야한다. 

 

반복문으로 게시글에 달린 답글들을 출력하는 템플릿 코드에서 답글 하나의 시작부분에 앵커태그를 추가한다.

앵커태그의 name은 유일한 값이어야 하기 때문에 answer_<답글id> 의 형태로 하였다.

 

3. 답글 작성, 수정 후 앵커 위치로 리다이렉트

 이제 답글을 작성하거나 수정하면 해당 위치의 앵커로 이동하도록 리다이렉트 함수를 수정해야한다.

 

먼저 django.shortcuts 에서 resolve_url 을 import 한다.  url resolve 는 url 매핑이 의미하는 실제 url주소를 문자열로

반환하는 함수이다. 그리고나서 redirect 되는 주소를 <게시글상세페이지 주소>/#answer_<작성/수정한 답글id> 의

형태로 수정해준다. 이동할 url의 뒷부분에 #앵커이름 을 추가해주는 것으로 그 페이지의 앵커이름에 해당하는 부분으로

이동할 수 있다.

 

 

답글을 작성해보면 리다이렉트되며 작성한 답글의 위치로 바로 이동하는 것을 확인할 수 있다.

 

 

4. 댓글에 앵커기능 추가

 답글과 동일한 방식으로 댓글에도 앵커기능을 추가할 수 있다.

 

 

게시글과 답글의 댓글영역 시작부분에 앵커를 추가해준다. 

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#28 검색과 정렬  (0) 2021.10.12
#27 마크다운(Markdown)  (0) 2021.10.11
#25 추천 기능  (0) 2021.10.10
#24 View 파일 분리하기  (0) 2021.10.10
#23 댓글  (0) 2021.10.07

이번에는 사용자가 게시글이나 답글에 추천(좋아요)을 할 수 있는 기능을 추가해본다.

 

1. 모델 변경

 당연히 먼저 Question 모델과 Answer 모델에 추천기능에 사용될 속성을 추가해야한다.

 

pybo/models.py 에서 Question, Answer 모델에 voter 속성을 추가한다.  그런데 저상태로는 마이그레이션 시에 에러가 발생한다.  User 모델에 연결된 속성이 author 와 voter 로 두 개이기 때문에 User 모델을 통해 Question 이나 Answer

인스턴스에 접근할 때 둘 중 어느것을 참조해야할지 모호해지기 때문이다. 

 

 

이를 해결하기 위해 author 와 voter 속성에 각각 related_name 인자를 추가해줘야 한다. 이제 어떤 유저가 작성한 게시글을 볼 때는 user.author_question.all(), 추천한 게시글을 볼 때는 user.voter_question.all() 과 같이 표현할 수 있다.

 

모델 수정이 완료되었으니 makemigrations 와 migrate 명령어를 실행하여 마이그레이션을 수행해준다.

 

 

2. 게시글 추천

 이제 본격적으로 게시글 추천 기능을 만들어야 한다.  먼저 게시글 상세페이지에 추천 버튼부터 생성해보자.

 

 먼저 추천영역과 기존의 게시글 내용과 답글을 표시하던 영역을 분리하기 위해 더 큰 영역을 만들어 추천 영역을

col-1 속성으로, 기존 부분을 col-11 속성으로 하는 것으로 추천:기존내용의 비율이 1:11로 나타나도록 하였다.

 

추천 링크의 href 값을 #으로 하고 data-uri 인자를 넣은 것으로 알 수 있듯이 여기서도 자바 스크립트 코드를 사용하여

정말 추천할것인지 확인창을 띄울 것이다. 삭제를 위해 만들었던 코드에서 메시지 내용을 수정하고 .delete 를

.recommend 로 수정하는 것으로 간단하게 기능을 구현할 수 있다.

 

pybo/urls.py 에 vote_question 에 해당하는 url 매핑도 추가해준다.  이전 게시글에서 views.py 파일을 분리했기 때문에

아직 생성하진 않았지만 뷰 함수인 vote_question 이 정의될 vote_views.py 파일의 import 문을 작성하고 vote_views.py

에 정의된 뷰 함수임을 명시하며 매핑을 추가해준다.

 

그리고 실제로 views 디렉토리에 vote_views.py 파일을 위와 같이 작성한다.  추천 또한 로그인한 사용자만이 게시글마다

1인당 한번에 한해서 추천이 가능하도록 하며 본인이 작성한 게시글을 추천하려고 할 경우 에러메시지를 출력한다. 

작업이 끝나면 게시글 상세 페이지로 리다이렉트 시켜준다.

 

이제 게시글 본문 옆에 받은 추천 수와 추천 버튼이 생겼음을 확인할 수 있다.  

 

추천 버튼을 누르면 추천할 것인지 확인 메시지가 나타나며

 

본인의 게시글을 추천할 경우 에러메시지가 표시된다.

 

다른 계정으로 로그인하여 추천할 경우 정상적으로 추천수가 올라가는 것을 확인할 수 있다.

 

 

3. 답글 추천

게시글 추천을 이미 구현해보았으니 답글 추천을 구현하는 것도 간단하다. 빠르게 구현해보자.

 

모델의 수정은 이미 게시글 추천을 구현할 때 마쳐두었기 때문에 바로 추천 영역을 만들어준다.  게시글 때와 완전히

같은방식으로 작성하고 question.voter.count 를 answer.voter.count 로, data-uri 값에서 uri 매핑과 넘겨줄 id를

answer 에 해당하는 것으로 바꿔주면 된다.

 

pybo/urls.py 에 url 매핑도 추가해준다. 

 

vote_views.py 에 vote_answer 함수를 위와 같이 구현해준다. 게시글 추천 함수에서 question 을 answer 로 바꿔주는

것만으로 완성이지만 redirect 시에 question_id 를 통해 게시글 상세 페이지로 이동해야 하기 때문에 answer.id 가

아니라 answer.question.id 를 넘겨주는 것에만 주의하면 된다.

 

이제 답글에도 정상적으로 추천기능이 동작하는 것을 확인할 수 있다.

 

 

4. 게시글 목록 페이지에서 추천수 표시하기

 게시글 목록 페이지에서도 추천수가 표시되도록 수정해보자.

 

question_detail.html 에서 테이블 헤더에 추천 항목을 추가하고 badge 형태로 question.voter.count 를 표시하도록 한다.

수정하는 김에 가운데 정렬 해주는 것이 보기 좋은 항목들은 가운데 정렬하여 표시하도록 수정해주었다.

 

이제 게시글 목록 페이지에서 게시글의 추천 수를 볼 수 있다.

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#27 마크다운(Markdown)  (0) 2021.10.11
#26 앵커  (0) 2021.10.11
#24 View 파일 분리하기  (0) 2021.10.10
#23 댓글  (0) 2021.10.07
#22 수정과 삭제  (0) 2021.10.07

Pybo 에도 슬슬 많은 기능이 추가되면서 pybo.views.py 파일의 크기가 제법 커졌다.  간단한 프로젝트이기 때문에 아직까진 큰 문제가 없지만 더 많은 기능이 추가된다면 한 파일에 너무 많은 함수가 공존하게되어 관리가 어려워질 것이다.

이번에는 views.py 파일을 분리하는 방법을 알아본다. 

 

1. 카테고리별 view 파일 생성

먼저 views.py 에 몰아넣어놨던 함수들을 카테고리화하여 별도의 파일들에 정의할 것이다. 현재 pybo/views.py 에

정의된 14개의 함수들을 다음과 같이 카테고리화 한다.

  • base_views.py (기본 관리)
    • index
    • detail

 

  • qeustion_views.py (게시글 관리)
    • question_create
    • question_modify
    • question_delete

 

  • answer_views.py (답글 관리)
    • answer_create
    • answer_modify
    • answer_delete

 

  • comment_views.py (댓글 관리)
    • comment_create_question
    • comment_create_answer
    • comment_modify_question
    • comment_modify_answer
    • comment_delete_question
    • comment_delete_answer

 

pybo 디렉토리 내에 views 디렉토리를 생성하여 그 안에 위 카테고리에 따라 함수를 별도의 파일에 정의하고

import 문을 정리해준다.(PyCharm 기준 Ctrl + Alt + O)  원래 같은 디렉토리에 있었던 models.py 나 forms.py

파일의 경우 view 디렉토리 내부로 파일이 이동하면서 상위디렉토리에 위치한 파일이 되었기 때문에 

from ..models ~ 와 같은 형태로 import 문을 변경해야한다.

 

마지막으로 views 디렉토리 내의 __init__.py 에 위와같이 분리한 파일내의 모든 함수를 import 해주는것으로 나머지

코드의 수정 없이도 기존처럼 사이트가 잘 작동한다.

 

 

2. views/__init__.py 파일 제거

 그런데 위의 방법에는 한가지 중대한 문제가 있다.  view의 어떤 함수가 어느 파일에 속해있는지 알 방법이 없다는

것이다.  특정 기능을 수정하기 위해서는 그 기능이 정의된 파일을 찾기위해 views 디렉토리 내의 모든 파일을 열어볼

필요가 생긴다.  이를 해결하기 위해서는 불편하더라도 views 디렉토리의 __init__.py 를 삭제한 다음 뷰 함수들이

호출된 파일들에 직접 import 문을 작성해줘야 한다.

 

pybo/urls.py 를 위와같이 수정해준다.  

 

config/urls.py 의 index 에 해당하는 매핑도 위와같이 수정해준다.

 

이제 어느 뷰 함수가 어느 파일에 정의되어있는지 한눈에 알 수 있다.  

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#26 앵커  (0) 2021.10.11
#25 추천 기능  (0) 2021.10.10
#23 댓글  (0) 2021.10.07
#22 수정과 삭제  (0) 2021.10.07
#21 글쓴이 표시  (0) 2021.10.04

1. 레드블랙 트리(Red-Black Tree)

 레드블랙 트리는 지난번에 다루었던 AVL 트리와 같은 자가 균형 이진 탐색 트리의 일종이다. 레드블랙 트리는

다음과 같은 조건을 만족한다.

  • 모든 노드는 색을 가지고있으며 색은 붉은색 또는 검은색 중 하나이다.
  • 루트 노드는 검은색이다.
  • 모든 리프 노드(NIL)는 검은색이다.
  • 붉은색 노드의 자식 노드는 검은색이다. => 붉은색 노드는 연속해서 나올 수 없다.
  • 모든 리프노드에서 Black Depth가 같다. 
    => 리프 노드에서 루트 노드까지 거슬러올라가며 만나는 블랙노드의 갯수가 모두 동일하다.

위 조건들을 만족함으로서 레드블랙 트리는 아주 중요한 특성을 가지게 된다. 모든 리프노드의 Black Depth가

같다면 그 사이에 붉은색 노드를 아무리 많이 끼워넣는다 해도 붉은색 노드는 연속으로 나올 수 없기 때문에

넣을 수 있는 붉은색 노드의 갯수는 (검은색 노드의 갯수 - 1) 개가 한계이다. 즉, 모든 리프노드의 깊이는

가장 얕은 리프노드의 깊이의 두 배를 넘을 수 없다.  이 특성 덕분에 AVL트리만큼은 아니어도 레드 블랙 트리는

상당히 균형잡힌 이진 탐색 트리가 된다.

 

2. 레드블랙 트리의 특징

  • AVL 트리와 마찬가지로 어떤 경우에도 삽입, 삭제, 검색에 O(logN)의 시간복잡도를 보장한다.
  • 매 삽입/삭제마다 최악의 경우 많은 회전 연산이 발생하는 AVL 트리에 비해 삽입/삭제에 걸리는 시간이
    비교적 적다.
  • 많은 프로그래밍 언어의 해시맵이나 집합 등의 라이브러리를 구현하는데에 레드블랙 트리가 활용된다.

 

3. 삽입/삭제시 Double-Red 처리 알고리즘

 레드블랙 트리는 삽입, 삭제 결과 발생한 규칙의 어긋남을 회전과 색변경을 통해 바로잡는다.   회전의 경우 AVL 트리에

사용했던 LL회전(right_rotation), RR회전(left_rotation)을 그대로 사용한다.  

 

① 삽입

 삽입 연산의 경우 문제의 발생여부를 아는것은 굉장히 간단하다. 삽입되는 노드는 기본적으로 붉은색 노드이기 때문에

삽입된 노드의 부모노드도 붉은색이라면 Double-Red 문제가 발생한다. 그리고 이 상태에서 문제해결은 삽입된 노드의
삼촌노드(부모 노드의 형제노드)의 색에 따라 두 가지 케이스로 나누어 진행된다.

  • Recoloring
    • 삼촌노드의 색이 붉은색일 경우 발생
    • 삼촌노드와 부모노드의 색을 모두 검은색으로 변경해준 다음 조부모노드(부모노드의 부모노드)의 색을 붉은색으로 변경해준다. 부모노드와 삼촌노드쪽 모두 검은색노드가 하나 늘어난 동시에 조부모노드가 붉은색이 되며
      일괄적으로 하나씩 줄었기 때문에 balck depth에는 영향을 주지않는다.
    • 다만 조부모 노드가 붉은색으로 바뀌면서 추가적으로 Double-Red 문제가 발생할 수 있기 때문에 조부모노드를
      새로 삽입한 노드로 취급하여 DoubleRed 처리를 재차 실행한다.
    • 즉, Recoloring은 한번 수행하고나서도 추가작업이 필요할 수 있다.
  • Restructuring
    • 삼촌노드의 색이 검은색일 경우 발생
    • 조부모노드 - 부모노드 - 삽입된 노드의 형태에 따라 회전 연산을 수행
    • LL 상태라면 조부모노드에 대해 right_rotation 수행
      RR 상태라면 조부모노드에 대해 left_rotation 수행
      LR 상태라면 부모노드에 대해 left_rotation 을 수행한 뒤 조부모노드에 대해 right_rotation 수행
      RL 상태라면 부모노드에 대해 right_rotation 을 수행한 뒤 조부모노드에 대해 left_rotation 수행
    • Restructuring 의 경우 이 작업만으로 더이상의 추가적인 Double-Red 문제가 발생하지 않기 때문에
      여기서 작업이 종료된다.
  • 모든 작업이 종료되면 루트노드를 검은색으로 바꿔준다.

 

② 삭제

 삭제연산은 조금더 복잡하다. 일반적인 이진탐색의 삭제연산의 경우 삭제할 노드의 좌측 서브트리중 최댓값 또는 
우측 서브트리중 최솟값을 가져와 삭제된 노드를 대체하는 형태로 이뤄진다.  레드블랙트리는 그렇게 삭제가 이뤄진 후 

규칙을 유지하기 위해 추가작업을 수행한다.  먼저 삭제된 노드 부분에는 문제가 발생하지 않는다.  삭제된 노드를
대체할 후임자 노드의 색을 삭제된 노드의 색으로 바꿔주면 되기 때문이다.  문제는 후임자 노드의 자리에서 발생한다.

삭제된 노드가 리프노드일 경우에는 삭제된 노드 자리를 대체한 NIL 노드가 C 노드가 되고 그 부모노드가 P 노드가

된다. C노드의 부모노드가 없는 경우에는 트리가 비어있는 상태이기 때문에 그대로 삭제연산을 종료한다.)

  • 후임자 노드가 붉은색일 경우
    • 후임자 노드가 붉은색이라면 사라지더라도 규칙에 아무 영향을 주지않는다.
  • 후임자 노드가 검은색이고 후임자 노드의 한쪽 자식노드가 붉은색인 경우
    • 후임자 노드가 검은색이어도 후임자 노드의 자식노드가 붉은색이라면 그 노드를 검은색으로 바꿔주면
      문제가 간단히 해결된다.

  • 후임자 노드와 후임자 노드의 한쪽 자식노드 모두 검은색인 경우
    • 이 경우가 가장 복잡한 상황이다. 이 경우 후임자 노드의 한쪽 자식노드 C를 기준으로 그 부모노드 P,
      형제노드 S, 가까운 조카노드 N1먼 조카노드 N2 의 상태를 기준으로 다섯가지 케이스로 나누어
      해결해나가야 한다. 여기서는 C가 P의 좌측 자식노드이고 S가 P의 우측 자식노드인 경우를 상정하여
      설명한다. 만약 반대로 C가 P의 우측 자식노드인 경우에는 회전 방향을 반대로 해야한다.

    • 케이스 1. P는 붉은색, S, N1, N2는 모두 검은색인 경우
      • P와 S의 색을 서로 맞바꾸는 것만으로 더이상의 추가작업 없이 간단히 해결할 수 있다.
      • 다섯가지 케이스중 가장 간단한 케이스이다.

    • 케이스 2. P, S, N1, N2 가 모두 검은색인 경우
      • S의 색을 붉은색으로 변경하는 것으로 C쪽과 S쪽 모두 검은색 노드가 하나씩 부족하도록 한다.
      • 결과적으로 부모노드 P 기준으로 검은색노드가 하나 부족하게되어 P 노드에 문제를 떠넘길 수 있다.
      • C 를 P로, P를 P의 부모노드로 재설정하여 다시한번 해당하는 케이스를 찾아 작업을 진행하도록 한다

    • 케이스 3. P, N1, N2는 검은색이고 S는 붉은색인 경우
      • P를 기준으로 left_rotation 을 수행한 뒤 P와 S의 색을 맞바꾼다. P의 색이 바뀌었기 때문에 바뀐 색상에
        따라 다시한번 해당 케이스를 찾아 작업을 진행하도록 한다.

    • 케이스 4. P의 색은 무관, S가 검은색이고 먼 조카노드 N2가 붉은색인 경우
      • P를 기준으로 left_rotation 을 수행한 뒤 P와 S의 색을 맞바꾼 뒤 먼 조카노드 N2를 검은색으로 변경한다.

    • 케이스 5. P의 색은 무관, S가 검은색이고 가까운 조카노드 N1은 붉은색, 먼 조카노드 N2는 검은색인 경우
      • S를 기준으로 right_rotation 을 수행한 뒤 가까운 조카노드 N1과 S의 색을 맞바꾼다.
      • 이 결과 케이스 4와 동일한 형태가 되니 계속해서 작업을 진행한다.

    • 위 작업을 케이스 1 또는 케이스 4 작업을 수행하여 추가작업이 필요없어지거나 C가 루트노드에 도달하여
      parent 노드가 존재하지 않을 때 까지 반복한다.

    • 모든 작업이 끝나면 루트노드를 검은색으로 바꿔준다.

 

글을 작성하면서 레드블랙트리를 직접 구현해보았지만 적은 양의 데이터로 하나하나 삽입, 삭제를 수행했을 때는

정상적으로 작동하는 것으로 보였지만 대량의 데이터를 삽입/삭제 해보니 삭제연산중에 문제가 있어 오류가 발생하는

경우가 나타났다. 나중에 시간이 되면 처음부터 다시한번 구현해볼 필요가 있을 것 같다.

 

추가) 2021.10.13

 좀더 알아보니 모든 노드가 좌우 자식노드로 검은색 NIL 노드를 가지도록 설계해야 구현이 쉬울 것으로 보여 설계를

처음부터 다시해보았다. 노드를 삽입할 때 삽입위치인 NIL 노드에 key값과 색상을 설정하고 좌우에 NIL 노드를 생성하여 붙이도록 했더니 삭제기능도 문제없이 작동하였다. 

 

1. 댓글 모델 작성

 이번에는 게시글과 답글에 댓글을 달 수 있는 기능을 추가해보기로 한다.

 

먼저 pybo/models.py 에 Comment 모델을 추가해준다. Answer 모델과 거의 유사하지만 답글의 경우

게시글과 답글 모두에 달릴 수 있기 때문에 외래키로 Question과 Answer의 객체 둘 다 받을 수 있어야 하며

둘 중 한쪽에만 값이 저장될 것이기 때문에 null=True, blank=True 로 설정하여 비워둘 수 있도록 해야한다.

 

모델이 변경되었으니 makemigrations 와 migrate를 수행해준다.

 

 

2. 게시글 댓글

 게시글에 댓글을 등록하는 기능을 추가한다.

 

먼저 question_detail.html 에서 게시글의 수정,삭제 버튼을 표시한 위치 바로 옆에 댓글창을 만들어준다. 이번에는 

댓글의 표시, 작성, 수정, 삭제 기능까지 모두 한번에 구현해보자.

 

댓글창의 디자인을 위해 부트스트랩 적용이후 사용하지 않았던 static 디렉토리의 style.css 를 위와 같이 수정해준다.

 

pybo/urls.py 에 새로 추가한 기능들에 사용된 url 매핑을 추가해준다.

 

pybo/forms.py 에 댓글을 입력받기 위한 CommentForm을 추가해준다.

 

pybo/views.py 에 댓글을 저장하기 위한 comment_create_question 함수를 구현한다.  답글을 저장하는 함수와 매우

유사하기 때문에 어렵지 않게 만들 수 있다.

 

댓글을 작성하기 위한 템플릿 comment_form.html 을 만들어준다.  이 역시 답글 작성을 위해 만들었던

answer_form.html과 거의 다르지않다.

 

댓글 수정을 위한 comment_modify_question 함수를 구현한다. 게시글이나 답글 수정과 거의 동일하다.

 

댓글 삭제를 위한 comment_delete_question 함수를 구현한다. 게시글이나 답글 삭제와 거의 동일하다.

 

이제 pybo에 접속해보면 로그인 상태에서게시글에 댓글을 달 수 있게 된것을 확인할 수 있다.

 

댓글이 정상적으로 등록되는 것을 볼 수 있다.

 

수정이나 삭제 기능도 정상적으로 작동하는 것을 확인할 수 있다.

 

3. 답글 댓글

 이제 답글에도 댓글 기능을 추가해주자.  이 작업은 게시글에 댓글기능을 추가하는것을 거의 그대로 반복하는

것이기 때문에 자세한 설명은 생략하도록 한다.

 

question_detail의 답글 부분에 댓글영역 추가

 

pybo/urls.py 에 url 매핑 추가

 

pybo/views.py 에 댓글 작성, 수정, 삭제 함수를 구현

 

이제 답글에도 댓글기능이 정상적으로 추가된 것을 확인할 수 있다.

'개인 프로젝트 > Django-mysite' 카테고리의 다른 글

#25 추천 기능  (0) 2021.10.10
#24 View 파일 분리하기  (0) 2021.10.10
#22 수정과 삭제  (0) 2021.10.07
#21 글쓴이 표시  (0) 2021.10.04
#20 모델 변경  (0) 2021.10.04

+ Recent posts