-
39일차 - 장고 프로젝트 (3)AI 솔루션 개발자과정(Java, Python) 2022. 12. 1. 18:54
포스트 목록 페이지 테스트
테스트 코드 작성은 만들고자 하는 코드의 내용을 정리하는 것부터 시작하는게 좋다.
포스트 목록 페이지는 앞에서 이미 만들었지만 아직 만들지 않았다 가정하고 테스트 코드를 만들어 보자.
처음에 만들려고 했던 포스트 목록 페이지의 디자인은 맨 위에 내비게이션 바가 있고, 그 아래는 포스트 목록이 있다. 옆에는 검색창과 카테고리가, 포스트 목록에는 제목과 작성일 등이 정리되어 나타난다.

blog/tests.py 에는 이런 형식으로 테스트 코드를 작성할 것이다.

모두 작성하면 이런식의 코드가 된다.
1.1 사용자가 블로그에 접속했을 때, 열리는 웹 페이지 정보를 response에 저장한다.
1.2 정상적으로 열렸다면 status_code의 값으로 200이, 웹페이지를 찾을 수 없을 때 404가 나온다.
1.3 불러온 페이지 내용은 HTML로 되어있다. Beautifulsoup로 읽어서 파싱한 결과를 soup에 담는다.
1.4 soup.nav로 <nav>태그만 추철해서 navbar에 저장한다.
1.5 navbar의 텍스트에 Blog와 About Me가 있는지 확인한다.
2.1 작성된 포스트가 0개인지 확인한다.
2.2 id가 'main-area'인 div 요소를 찾아 main_area에 저장한다.
3.1 objects.create()로 포스트를 만들 수 있다.
3.2 페이지를 새로고침하기 위해 1.1부터 1.3의 과정을 일부 반복한다.
3.3 새로 만든 두 포스트의 타이틀 id가 'main-area'인 요소가 있는지 확인한다.
3.4 포스트가 생성되었으니 '아직 게시물이 없습니다.' 라는 문구가 메인 영역에 더 이상 나타나면 안된다.
아직 id가 'main-area'인 요소가 없기 때문에 당연히 오류가 발생한다.

post_list.html에 해당 id를 추가한다.
또한 아직 게시물이 없습니다. 라는 문구를 출력하도록 if문을 이용하여 추가한다.

테스트 코드에서 처럼 count() 함수를 사용하는 대신 exists() 함수를 사용한 이유는 함수가 서버에 부담을 덜 주기 때문이다.
이제 포스트 상세 페이지를 테스트할 코드를 작성한다.


1.1 함수를 실행하면 새로운 데이터베이스를 만들고 포스트를 하나 생성한다.
1.2 이 포스트의 url은 '/blog/1/'이 된다.
2.1 해당 url로 접근하면 정상적인 상태코드를 반환하는지 확인한다,
2.2 내비게이션 바의 텍스트가 포스트 목록 페이지와 같은지 점검한다.
2.3 이 포스트의 title이 브라우저 탭의 타이틀에 있는지 확인한다.
2.4 메인 영역에서 포스트 영역만 불러오는 내용이다. 포스트의 title이 메인영역에 있는지 확인한다.
2.5 아직 작성자 영역을 만들지 않았기 때문에 패스한다.
2.6 post_001의 내용이 포스트 영역에 있는지 확인한다.
이 테스트 코드를 실행하면 당연하게도 실패한다.
블로그 상세 페이지의 내비게이션 바를 수정하지 않았기 때문이다.
이 이외의 오류가 없다면 여기에서 커밋과 푸쉬를 한다.
템플릿 모듈화
대부분의 웹 사이트는 내부의 다른 페이지를 열어도 일관된 페이지 디자인을 유지한다.
어떤 페이지를 열어도 내비게이션 바와 푸터는 그대로 유지되어야 사용하기 편리하고 보기 좋다.
이렇게 페이지에서 반복되는 요소는 페이지마다 소스를 중복해서 사용하기보단 모듈화해서 관리해야 한다.
메인 영역 모듈화
지금 만들고 있는 목록 페이지와 상세 페이지는 내비게이션 바와 메인 영역을 제외한 푸터와 사이드 메뉴는 동일하다. 이러한 상황에서는 메인 영역을 뺀 나머지 영역을 하나의 페이지에 만들어놓고 목록 페이지일 때와
상세 페이지일 때를 구분하여 상황에 맞게 메인 영역만 채워주면 편해진다.
먼저 post_list.html파일을 모듈화하는데, 파일을 복사하여 파일명을 base.html로 수정한다.
base.html은 공통 영역만 남기기 위한 파일이다.
base.html에서 id='main-area'인 div 요소의 내부를 모두 삭제한다. 이때 <div>태그의 시작과 끝이 잘 남아 있도록 주의하여 삭제한다.
그리고 다음과 같이 {% block main_area %}와 {% endblock %}을 추가하여 블록을 만든다.

그리고 이 블록에 들어갈 영역을 post_list.html파일로 만든다.
post_list.html은 base.html에서 삭제한 내용을 남기고 나머지를 지운다.

길었던 post_list.html의 내용이 이렇게 간략해졌다.
여기까지 수정한 내용에 이상이 있는지 확인하기 위해 터미널에서 테스트를 진행한다.
당연히 post_detail.html은 수정하지 않았기 때문에 실패가 뜨기에, test_post_list 함수만 실행한다.

테스트는 무사히 통과했다.
이제 나머지 post_detail.html도 base.html을 이용할 수 있도록 수정한다. 위와 같이 메인 영역에 해당하는 부분만 남기고 다 지운 후 블록을 지정한다.
현재 post_detail.html은 <div class="container">안에 <div class="row">가 있고, <div class="col-lg-8">안에 있는 내용만 남기면 된다.

즉, 내용이 들어가는태그 위쪽 내용과,

댓글 코맨드가 있는 내용 아랫부분을 지우면 된다.
이후 다시 터미널에서 테스트를 진행하면 또 오류가 발생하는데,

웹 브라우저 위쪽에 나타나는 타이틀이 없다는 것이다. 웹 브라우저의 타이틀은 <head> 태그에 있고, 이 태그는 base.html에 위치해 있다.
post_detail.html에 다음과 같이 블록을 하나 더 만든다.

이 블록에 base.html에서 받아온 head.title을 불러온다.
base.html은 다음과 같이 추가한다.

이렇게 하면, base.html을 extends한 다른 템플릿 파일에 head_title블록이 있을 경우 여기에 채워 넣게 된다. post_list.html처럼 head_title이 명시되어 있지 않은 경우 기본값이 Blog를 사용하는 구조이다.
다시 테스트를 진행한다.

이번에는 이전의 오류와는 다른 오류가 발생했다.
이건 post_detail.html에서 포스트 영역과 댓글 영역을 구분하지 않아서 발생한 오류이다.

post_detail.html에서 포스트 영역에 해당하는 부분은 id="post-area" 인 <div>태그로, 댓글 영역에 해당하는 부분은 id="comment-area"인 <div>태그로 감싼다.
다시 테스트를 실행하면 더이상 오류가 발생하지 않는다.

내비게이션 바와 푸터 모듈화
지금까지는 포스트 목록이나 상세 페이지 등으로 가기 위해 직접 URL주소를 입력했다.
내비게이션 바의 링크가 제대로 설정되지 않아 버튼을 클릭하면 엉뚱한 경로로 가기 때문이다.
테스트 코드에서는 내비게이션 바에 'Blog'와 'About Me' 라는 문구만 확인했기에 테스트는 통과되었다.
문제의 원인은 base.html의 내비게이션 바 소스코드를 보면, 각 버튼의 링크를 장고의 urls.py에서 처리하지 못하기 때문이다. 이를 urls.py에서 처리할 수 있도록 수정해야 한다.
먼저 내비게이션 바의 정상 유무를 확인하는 테스트 코드를 작성한다.
테스트 코드는 test_post_list() 함수와 test_post_detail() 함수에 동일하게 들어있다.
이 부분을 잘라내어 새로운 함수로 따로 만든다.
내비게이션 바를 점검하는 함수명은 navbar_test()로 한다.
TestCase를 사용했을 때, 함수 이름을 test로 시작하면 test_post_list()나 test_post_detail()함수처럼 테스트를 위한 함수라고 인식하기 때문이다.
이 함수들에서 beautifulsoup를 통해 파싱된 HTML요소를 navbar_test()함수에서 받아 사용하기 위해
매개변수로 soup를 지정한다.

다시 터미널에서 테스트를 진행해보면 이전과 마찬가지로 아무 문제가 발생하지 않는다.
이 navbar_test() 함수는 내비게이션 바에 있는 버튼을 클릭했을 때 제대로된 링크로 연결되는지 확인한다.
해당 경로로 잘 이동하는지 점검하는 코드를 추가한다.

먼저 테스트를 진행해보면, 다음과 같이 오류가 발생한다.

logo_btn 버튼의 href값이 '/'가 아니라 '/index.html'이라서 오류가 발생한 것이다.


이 base.html의 내비게이션 바를 다음과 같이 수정한다.

4개의 href값과 Home 버튼의 <span>태그만 변경하였다.
Home버튼의 <span class="sr-only"> 태그는 화면에는 나타나지 않고, 스크린 리더로만 읽을 수 있는, 화면에 나타나는 정보를 음성으로 출력해 주는 프로그램이다.
웹 접근성을 높이기 위해 사용하면 좋지만, 지금까지 배운 내용으로 이 기능을 구현하기 힘들기에 삭제한다.

터미널에서 테스트를 해보면 OK가 출력된다.
웹 사이트의 디자인 통일성을 위해 내비게이션 바와 푸터는 나중에 손볼 대문 페이지, 자기소개 페이지에도 동일하게 적용되어야 한다.
그렇기 때문에 base.html의 <nav> 태그와 <footer>태그를 따로 관리하면 편하다.
이때 장고의 include를 사용하면 HTML을 요소별로 분할해 관리하고 불러올 수 있다.
먼저 blog/templates/blog 폴더에 navbar.html 을 만든다.
그리고 base.html의 <nav>태그부터 그 아래 모달에 관련된 코드까지 잘라 옮긴다.

base.html에서 생긴 빈 공간을 {% include 'blog/navbar.html' %}로 채워넣는다.
나중에 base.html을 사용할 때 이 위치에서 navbar.html의 내용을 그대로 가져와서 붙여넣는것과 동일한 효과를 얻을 수 있다.
마찬가지로 푸터도 모듈화 한다. 같은 폴더에 footer.html파일을 만들고 옮긴다.

다시 테스트를 진행해서 내비게이션 바를 점검하고, 서버를 실행하여 잘 동작하는지 확인한다.
다대일 관계 구현하기
이 장에서는 Post모델에 작성자와 카테고리 기능을 구현한다.
이들은 다른 모델끼리 연결해야 만들 수 있다.
웹 개발을 하다 보면 각기 다른 정보를 연결해야 할 때가 있다.
방문자가 포스트에 댓글을 달았다면, 이 댓글이 어떤 포스트에 대한 댓글이고 작성자는 누구인지 등의 정보를 담을 필드가 필요하다.
이렇게 정보를 연결하는 방법으로는 다대일 관계와 다대다 관계가 있다.
다대일 관계는 여러 개의 모델이 하나의 모델에 연결되는 관계를 말한다.
블로그 사용자는 여러 개의 포스트를 작성할 수 있다. 각각의 포스트에는 하나의 사용자 정보만 담을 수 있다.
즉 포스트와 작성자의 관계는 다대일 관계이다.
그리고 각 포스트는 하나의 카테고리를 갖는다. 이 또한 다대일 관계가 성립된다.
작성자 필드에는 사용자 이름을 문자열로 저장해야 한다. 또한 그 사용자가 이름을 바꿨을 경우 이전에 작성한 포스트의 작성자명도 함께 바뀌어야 하고, 탈퇴하거나 글을 삭제하면 작성자명을 'unKnown'으로 표시하는 기능도 필요하다.
이렇게 작성자 필드에는 여러 기능이 필요하기 때문에 따로 만든 다음 포스트와 연결하는 것이 좋다.
이러한 다대일 관계에서는 foreignKey(외래키)를 활용한다.
먼저, User 모델을 사용할텐데, User 모델은 장고에서 기본적으로 제공하는 모델이다.

먼저, User 모델을 사용해야 하기 때문에 blog/models.py를 이처럼 수정한다.
from django.contrib.auth.models import User로 임포트하고,
author = models.ForeignKey(User, on_delete=models.CASCADE)를 추가한다.
자동완성 기능을 사용하면, CASCADE()로 함수호출문이 작성될텐데, 여기서는 함수호출문이 쓰이면 안된다.
CASCADE는 작성자가 데이터베이스에서 삭제되었을 때, 포스트도 같이 삭제한다는 의미이다.
마지막으로 포스트 목록에서 작성자 정보까지 출력되도록 __str__()함수를 수정한다.
모델을 수정했으므로 마이그레이션을 진행한다.

하지만 이러한 오류가 발생하는데, 이는 Post모델의 레코드가 여러 개 존재하기 때문에 새로 만드는 author 필드를 비워둘 수 없으니 뭔가를 채워 넣어야 한다는 것이다.
1)을 선택하게 되면 이미 존재하는 Post 레코드의 author에 바로 값을 넣을 수 있다.
또는 2)를 선택하고 빠져나와 위에서 작성한 author 필드를 수정할 수 있다.
지금은 1)을 선택하고 1을 입력하여 이전에 만들어둔 User를 선택하고 마이그레이션을 진행한다.
마이그레이션이 끝나면 다시 서버를 실행하고 관리자 페이지에 들어간다.

포스트에 들어가면 Author 입력란이 생겼다. 마이그레이션에서 지정한 대로 작성자가 1번 User인 것도 확인할 수 있다.
먼저 다른 사용자가 다른 게시물을 작성하는 경우를 테스트 하기 위해 새로운 사용자를 만든다.
User 옆에 + 버튼을 클릭해서 name과 password를 입력하여 생성할 수 있다.
이제 새로운 사용자를 이용하여 새 포스트를 작성한다.
Posts에서 포스트 목록을 보면 새로 작성한 포스트에 새로운 사용자 이름까지 출력되는 것을 확인할 수 있다.

성공적으로 새로운 사용자의 글이 작성되었고, 포스트 타이틀 옆에 작성자 이름이 보인다.

models.py를 수정하면서 사용자가 삭제되었을 때 사용자의 포스트까지 삭제한다고 설정했었다.
Users에서 새로 만든 사용자를 삭제하면,

포스트까지 함께 사라지는 것을 확인할 수있다.
이번에는 사용자가 삭제되어도 사용자가 작성한 글은 남겨두고 author 필드값만 null로 바뀌도록 설정한다.

models.py에서 CASCADE를 SET_NULL로 변경한다.
여기서도 마찬가지로 함수호출문이 오지않도록 괄호를 삭제해준다.
이후 모델을 수정했으니 마이그레이션을 진행하는데 다음과 같은 오류 메시지가 출력된다.

마지막에 수정한 SET_NULL은 null일수 없다고 쓰여있으니, 중간에 null=True 를 추가해준다.

다시 마이그레이션 해주면 성공적으로 반영된다.
테스트를 위해 다시 관리자 페이지에서 새로운 포스트를 추가하고 유저를 삭제한다.

posts에서 확인해보면 포스트는 그대로이지만, 작성자는 None으로 바뀌었다.
이제 작성자 정보가 포스트 목록과 상세 페이지에 나타나도록 만든다.

blog/tests.py를 이렇게 수정한다. 이는 테스트용 사용자를 생성하는 코드이다.

또한 테스트용 포스트가 생성될 때 작성자를 테스트용 사용자로 지정하도록 test_post_list()함수에 코드 4줄을 추가한다.

테스트를 진행하면 이러한 오류가 나오는데, author가 보이지 않는다고 한다.
post_list.html에서 >작성자명 쓸 위치< 를 {{ p.author | upper }} 을 입력한다.



정상적으로 테스트가 완료되었다.
위의 과정을 포스트 상세 페이지에도 적용한다.


서버를 실행해서 웹 브라우저를 확인해보면 성공적으로 작성자가 표시된다.

카테고리 기능 구현하기
사이드 바의 카테고리 카드에 블로그의 카테고리가 모두 표시되야 하는데, 이들은 포스트 목록 페이지와 상세 페이지에 모두 나타나야 한다.
이중 하나를 클릭하면 해당하는 카테고리에 포함된 포스트가 모두 나열되어야 한다.
포스트는 하나의 카테고리에만 지정할 수 있다. 반대로 카테고리에는 여러 개의 포스트가 포함될 수 있다.
즉, 포스트와 카테고리의 관계는 포스트와 작성자의 관계처럼 다대일 관계이다.
작성자 필드는 장고에서 제공하는 User 모델로 구현했지만, 이번에는 직접 Category 모델을 개발한다.
먼저, blog/models.py에 Category 모델을 다음과 같이 추가한다.

카테고리 모델에는 name과 slug라는 이름의 필드를 만들었다.
name필드는 카테고리의 이름을 담는 필드로 많이 활용한 CharField를 사용했고, unique=True를 추가했다.
unique=True로 설정한다면, 각 카테고리 이름의 중복이 불가능해 진다.
slug는 url을 생성하기 위해 문자를 조합하는 방식을 뜻한다.
slug필드의 SlugField는 사람이 읽을 수 있는 텍스트로, 고유 URL을 만들고 싶을 때 주로 사용한다.
카테고리 모델도 포스트 모델처럼 pk를 활용해 URL을 만들 수 있지만 포스트만큼 개수가 많지 않을 것이기 때문에 사람이 읽고 그 뜻을 알 수 있게 고유 URL을 사용한다.
또한 allow_unicode=True로 설정해서 한글로도 만들 수 있게 했다.
이제 포스트 모델에 외래키로 카테고리 필드를 추가한다.
카테고리 분류가 안된 포스트도 있을 수 있기 때문에 null=True로 설정한다.
또한 카테고리가 삭제될 때, 연결된 포스트는 삭제되지 않도록 on_delete=models.SET_NULL로 설정한다.

모델을 수정했으니 마이그레이션을 진행한다.
이제 관리자페이지에서 카테고리 모델을 사용하도록 blog/admin.py에 모델을 등록한다.

카테고리 모델을 사용하기 위해 import에 추가해주고,
prepopulated_fields = {'slug': ('name', )}이 코드는 카테고리 모델의 name필드에 값이 입력되었을 때 자동으로 slug가 만들어지는 코드이다.

서버를 실행하고 관리자 페이지를 확인해 보면 카테고리 메뉴가 추가되었다.
Meta로 모델의 복수형 수정하기.
Category의 복수형은 Categories이다. 위의 카테고리 메뉴는 스펠링이 잘못되었으니, models.py를 열고 Category 모델의 메타 설정에서 verbose_name_plural을 추가해 복수형을 직접 지정한다.

수정 후 다시 관리자 페이지를 새로고침하면 수정된 텍스트가 나타난다.

카테고리 생성 페이지에서 카테고리 이름을 작성하면, 자동으로 특수기호나 빈칸 등 URL로 사용하기 적합하지 않은 문자를 적절하게 변환한 다음 Slug에 채워준다.
카테고리를 생성하고, 이전에 생성한 포스트를 들어가서 Category를 설정하지 않고 저장한다면,
아까 null=True를 설정했으니 저장이 될 것 같지만 저장이 되지 않는다.
blog/models.py에서 Post모델의 category필드에 blank=True를 추가로 지정한다면 관리자 페이지에서 카테고리를 빈 칸으로 지정할 수 있게 된다.

모델을 수정했으니 자연스럽게 마이그레이션을 진행하고 다음으로 넘어간다.
장고 셸 이용하기.
관리자 페이지에서 몇 개의 포스트를 생성 후 서로 다른 카테고리에 연결한다.
다시 터미널로 돌아와 서버를 중단하고, python manage.py shell을 입력해 장고 셸을 실행한다.
장고 셸에서는 장고가 제공하는 기능들과 지금까지 장고로 개발한 내용을 불러올 수 있다.
먼저, from blog.models import Post, Category로 지금까지 만든 포스트모델과 카테고리 모델을 불러온다.
그리고 post.objects.count()로 몇 개의 포스트가 데이터베이스에 저장되어 있는지, Category.objects.count()로 몇 개의 카테고리가 있는지 확인한다.

각각 5개와 3개가 존재한다.
for문을 활용해 데이터베이스에 저장된 모든 Post 레코드와 Category 레코드를 출력해 본다.


관리자 페이지에서 보았던 목록과 비슷하게 한 줄씩 출력된다.
이번엔 장고 셸이 아닌 셸 플러스(shell plus)를 사용해 보자.
exit()로 장고 셸을 종료하고, pip install django_extenstions, pip install ipython 을 설치한다.
설치 후 do_it_django_prj/settings.py 에서 INSTALLED_APPS리스트에 django_extensions를 추가한다.

이제 터미널에 python manage.py shell_plus를 입력하면 셸 플러스가 실행된다.
셸 플러스를 이용하면 파이썬 코드에 따라 글자 색상이 다르게 표현되어 가독성이 높아지고, for 문을 사용할 때 들여쓰기도 자동으로 맞춰져 편리하다. 또한 포스트 모델과 카테고리 모델을 import하지 않아도 가져와 쓸 수 있다.

또한 다음과 같이 slug값이 일치하는 카테고리나, name이 '문화'로 시작하는 카테고리를 가져올 수도 있다.

카테고리에 포함된 포스트도 출력할 수 있다. 이때 모델명을 소문자로 쓰고, _set을 붙이는게 기본 설정이다.

포스트 목록 페이지 수정하기
카테고리 모델도 만들었으니, 이제 사용자가 이를 선택할 수 있게 해야 한다.
카테고리 카드에 카테고리 이름을 나열하고, 그 옆에 카테고리에 있는 포스트 개수를 괄호 안에 표시하도록 대략적인 구상을 짠다.
그 다음은 테스트 주도 개발에 맞게 테스트 코드를 작성한다.
먼저, setUp() 함수에 programming과 music이라는 이름으로 카테고리 레코드를 2개 만든다.
setUP() 함수는 TestCase의 초기 데이터베이스 상태를 정의할 수 있기 때문에 같은 클래스 안에 있는 다른 테스트 함수에 공통적으로 적용이 된다.
따라서 TestView 클래스 내의 모든 테스트를 시작할 때 이미 테스트 데이터베이스에 카테고리가 2개 생성되어 있는 상태로 만들 수 있다.

앞으로의 테스트는 미리 생성되어 있는 상태로 진행하기 위해, 다른 테스트함수에서 생성할 포스트들도 setUp()함수로 옮기고, 미분류로 처리될 포스트까지 하나 추가로 생성한다.
또한 카테고리에 모든 카테고리가 제대로 출력되어 있는지 확인하는 함수를 추가한다.

test_post_list()함수는 다음과 같이 대폭 수정한다. 포스트가 있는 경우와 없는 경우를 나눠서 테스트한다.

테스트를 진행하면 FAILED가 출력된다.
base.html에서 카테고리 카드에 해당하는 div요소에 아직 id를 부여하지 않아 발생한 문제이다.
카테고리 위젯을 찾아 다음과 같이 수정한다.

다시 실행하면 이러한 오류로 변경된다.

'programming(1)이 없어 발생한 오류이다. 이 오류는 blog/views.py에서 Category 레코드를 가져와 post_list.html에 반영되야 해결된다.
views.py를 다음과 같이 수정한다.

웹 브라우저에서도 카테고리가 보이기 위해서 base.html도 수정한다.


그럼 오류는 이렇게 변하는데, post_list.html을 수정하여 for문 안에 반복되는 <div class="card mb-4"요소에 id를 추가한다.

그리고 <span>태그를 추가하고, 부트스트랩에서 제공하는 뱃지를 사용해 카테고리를 표현하는 코드를 추가한다.

포스트 상세 페이지 수정하기
포스트 상세 페이지 테스트를 담당하는 test_post_detail()함수는 조금만 수정하면 된다.

post_001은 앞에 self.만 붙여주면 되고, 포스트를 생성하는 문장은 지운다.
중간에 category_card_test 구문만 추가한다.

카테고리 카드를 채우기 위한 정보를 views.py의 PostDetail 클래스에서 정의해 주지 않았기 때문에 context_data를 이용해 넘겨준다.
super(PostList, self)를 super(PostDetail, self)로 수정하고 PostList 클래스에서 사용한 코드를 복사 붙여넣기 한다..

post_list.html에서 활용했던 코드를 그대로 복사 붙여넣기 한다.
카테고리 페이지 만들기

tests.py에 카테고리 페이지 테스트코드를 추가한다.

models.py를 수정하여 고유URL을 만들도록 하고, 이 URL을 처리할 수 있도록 urls.py도 수정한다.

사용자가 category/뒤에 문자열이 붙은 URL을 입력하면 그 문자열을 views.py에 정의한 함수의 매개변수인 slug의 인자로 넘겨준다.
이제 views.py에 FBV로 category_page() 함수를 만든다.

함수의 매개변수로는 FBV방식에 꼭 필요한 request 외에 slug까지 설정했다.
그리고 URL에서 추출하여 함수의 인자로 받은 slug와 동일한 slug를 갖는 카테고리를 불러오는 쿼리셋을 만들어 category변수에 저장한다.
post_list = Post.objects.filter(category=category)는 위의 과정에서 포스트 중에서 변수에 저장한 쿼리셋으로 필터링한 카테고리만 가져와 라는 의미이다.
post_list.html에 카테고리 페이지에 추가한 뱃지가 포스트 목록 페이지에서 보이면 안된다. 따라서 다음과 같이 if문을 사용해 카테고리가 context로 넘어올 때만 그 카테고리 이름을 부트스트랩의 뱃지 형태로 출력한다.


미분류 카테고리를 처리하기 위해서 views.py를 수정하여 category_page()함수의 slug인자로 'no_category'가 넘어오는 경우 카테고리가 없는 포스트만 보여주고, 미분류 라는 문자열만 저장한다.

테스트 결과 무사히 통과 되었다. 서버를 실행하고 확인해보자.
확인했으면 깃에 커밋과 푸쉬하자.
'AI 솔루션 개발자과정(Java, Python)' 카테고리의 다른 글
41일차 - 장고프로젝트 (5) (0) 2022.12.05 40일차 - 장고 프로젝트 (4) (0) 2022.12.02 38일차 - 장고 프로젝트 (2) (0) 2022.11.30 37일차 - 장고 프로젝트 (2) 2022.11.29 36일차 - 장고 + 부트스트랩 파이썬 웹 개발 (1) 2022.11.28