게시판 (2)

Codren·2021년 5월 12일
0

Django 기초

목록 보기
13/15

Section 1. 페이징 (Paging)

1. URL vs URI

  • URL - 인터넷 상의 자원의 위치
  • URI - 인터넷 상의 자원의 식별자 (URL + 식별자 id)
  • URL 끝에 ? or /? 는 여기부터는 식별자 id를 부여하는 변수 부분임을 지정하는 의미
  • '?'를 기점으로 모두 변수 취급하므로 아래와 같은 결과를 얻어 낼 수 있음
# list/ 까지는 urls.py에 정의되어 있고 ? 뒤는 모두 변수 취급이기 때문에 정상표시 됨
# view에서 page = int(request.GET.get('p', 1))로 처리하므로 지정된 변수가 아니면 모두 1페이지 표시

http://127.0.0.1:8000/board/list/?p=1		# 정상 표시 (1페이지)
http://127.0.0.1:8000/board/list/?p=2		# 정상 표시 (2페이지)
http://127.0.0.1:8000/board/list/?test		# 정상 표시 (1페이지)


# list/p 는 변수 취급이 아닌 url로 취급됨

http://127.0.0.1:8000/board/list/p		# 페이지 오류



2. Template 생성

  • 이전 또는 다음 페이지가 있는 경우와 없는 경우로 나눔
  • bootstrap 의 disabled 클래스는 a 태그가 아닌 li 태그에 적용
{% if boards.has_previous %}		# 현재 paginator의 페이지의 이전 페이지가 있다면
{% if boards.has_next %}		# 현재 paginator의 페이지의 다음 페이지가 있다면
{{ boards.number}}			# 현재 페이지의 번호
{{ boards.paginator.num_pages}}		# paginator의 전체 페이지 번호 (수)

href="?p={{ boards.previous_page_number }}"	# 현재 URL+?p = 현재 페이지의 이전 페이지
href="?p={{ boards.next_page_number }}"		# 현재 URL+?P = 현재 페이지의 다음 페이지



3. View 생성

  • Paginator 객체 이용 (from django.core.paginator import Paginator)
  • request.GET.get('변수') 를 이용하면 URI에서 해당 변수 값을 추출 가능함

all_boards = Board.objects.all().order_by('-id')	# Board 테이블에 있는 모든 행들을 id 역순으로 불러옴
paginator = Paginator(all_boards, 2)			# 불러온 행들을 2개씩 페이징
page = int(request.GET.get('p', 1))			# URL/?변수들 에서 변수 p의 값을 추출, 없다면 1로 설정 
boards = paginator.get_page(page) 			# 해당 page에 존재하는 board 행만을 넘김



4. 페이징 결과 화면




Section 2. 태그 (Tag)

1. Tag app 생성 및 등록

python manage.py startapp tag



2. Model 생성 및 Migration



3. Board Model 수정

  • Board 테이블과 Tag 테이블은 tags 속성으로 N:M 관계
  • models.ManyToManyField 이용



4. N:M 관계 테이블

  • models.ManyToManyField 를 이용해서 N:M 관계 정의하면 아래와 같은 결과 생성
  • board_tags 테이블 (주키는 board_id 와 tag_id) 생성
  • board 테이블과 tag 테이블 사이에 board_tags 테이블 생성되어 1:N - M:1 로 매핑



5. Admin 등록



6. Admin add 화면

  • admin 페이지에서 add 로 태그를 미리 생성해 놓음
  • 다음과 같이 board 게시글 작성 시에 태그를 지정할 수 있음



7. Template 변경

  • board.tags 는 N:M 관계이므로 원자값이 아닌 다중값일 경우도 있음
  • board -> board_tag -> tag 행 추출, 이런 순서로 접근하는 개념
  • all, last 는 해당 행을 가리키는 함수 그 자체, all(), last()는 해당 행 그 자체
{% for tag in board.tags.all %} 	# 해당 board 게시글에 지정된 모든 tag 행들
{{ tag.name }} 				# {{ tag }} 와 동일 (__str__함수)

{{ board.tags.all|join:", "}}		# 이렇게 '|' 이용하여 문자열 함수 기능 사용할 수 있음
					#  이 코드 한 줄로 동일한 결과 얻어낼 수 있음

* {% for loop %} 으로 출력되는 문자 사이에는 ' ' 공백 문자 들어감 (ex. 태그1, 태그2 이런식)


8. 태그 출력 화면




Section 3. 게시판 글 쓰기에서 Tag 등록

1. 게시판 글 쓰기 form 수정

  • required = False 는 Null 값 허용



2. 게시판 글 쓰기 view 수정

  • board_tags 테이블은 board, tag 테이블의 주키를 참조하므로 board, tag 존재 선행 필수
    board.save() -> board.tags.add() 순서
  • form에서 ',' 를 구분자로 태그를 입력하므로 .split(',') 을 이용하여 분리한 뒤 리스트로 반환
  • get_or_create() 함수는 객체와 원래 존재 여부에 대한 값을 반환
  • _tag 는 하나의 값이 아닌 하나의 인스턴스 (행)

tags = form.cleaned_data['tags'].split(',')	# 입력된 태그들을 ',' 구분자로 분리한 뒤 리스트 반환 (' ' 스페이스바 문자까지 태그로 인식)
_tag, _ = Tag.objects.get_or_create(name=tag)	# 2개의 반환값을 받는데 '_'는 이용하지 않겠다는 의미
board.tags.add(_tag)				# board 테이블의 tags 속성에 _tag 행을 삽입 (=참조_

0개의 댓글