작성
·
383
·
수정됨
0
안녕하세요 선생님. 강의 열심히 듣고 있습니다^^;
다름이 아니라 아래와 같이 미분류 카운트가 입력되지 않아 오류가 발생하는 부분때문에 계속 찾아보았으나,
답답한 마음에 질문글을 남깁니다.
우선 카테고리 분류에서
프로그래밍, 문화&예술 까진 카운트가 잘 입력됩니다.
그렇지만 "미분류" 부분은 계속 () 으로 표시됩니다.
분명 미분류 부분이 존재함에도 불구하고, 카운트가 되지 않는 건 무엇이 잘못되었는지 도저히 알기가 어렵습니다. 혹시 확인이 가능할까요?^^;;
test.py 실행시 오류화면
미분류() 카운트 부분을 주석처리하면 테스트는 잘 완료됩니다.
총 4개의 페이지에 대한 코드를 올려봅니다.
from django.test import TestCase, Client
from django.contrib.auth.models import User
from bs4 import BeautifulSoup
from .models import Post, Category
# Create your tests here.
class TestView(TestCase):
def setUp(self):
self.client = Client()
# 방문하는 사람의 브라우저다 Client()
self.user_trump = User.objects.create_user(
username='trump',
password='somepassword'
)
self.user_obama = User.objects.create_user(
username='obama',
password='somepassword'
)
self.category_programming = Category.objects.create(
name='programming', slug='programming'
)
self.category_music = Category.objects.create(
name='music', slug='music'
)
self.post_001 = Post.objects.create(
title='첫 번째 포스트입니다.',
content='Hello, world, we are the world',
category=self.category_programming,
author=self.user_trump,
)
self.post_002 = Post.objects.create(
title='두 번째 포스트입니다.',
content='1등이 전부는 아니잖아요. 저는 개발을 좋아할겁니다.',
category=self.category_music,
author=self.user_obama,
)
self.post_003 = Post.objects.create(
title='세 번째 포스트입니다.',
content='Category 가 없을 수도 있죠.',
author=self.user_obama,
)
def navbar_test(self, soup):
navbar = soup.nav
self.assertIn('Blog', navbar.text)
self.assertIn('about_me', navbar.text)
logo_btn = navbar.find('a', text='Do it Django')
self.assertEqual(logo_btn.attrs['href'], '/')
home_btn = navbar.find('a', text='Home')
self.assertEqual(home_btn.attrs['href'], '/')
blog_btn = navbar.find('a', text='Blog')
self.assertEqual(blog_btn.attrs['href'], '/blog/')
about_me_btn = navbar.find('a', text='about_me')
self.assertEqual(about_me_btn.attrs['href'], '/about_me/')
def category_card_test(self, soup):
categories_card = soup.find('div', id='categories-card')
self.assertIn('Categories', categories_card.text)
self.assertIn(
f'{self.category_programming} ({self.category_programming.post_set.count()})',
categories_card.text
)
self.assertIn(
f'{self.category_music} ({self.category_music.post_set.count()})',
categories_card.text
)
self.assertIn(
f'미분류 ({Post.objects.filter(category=None).count()})', categories_card.text
)
def test_post_list_with_posts(self):
self.assertEqual(Post.objects.count(), 3)
# 1.1 포스트 목록 페이지 (post_list)를 연다.
response = self.client.get('/blog/')
# 1.2 정상적으로 페이지가 로드된다.
self.assertEqual(response.status_code, 200)
# 1.3 페이지 타이틀에 Blog 라는 문구가 있다.
soup = BeautifulSoup(response.content, 'html.parser')
self.assertIn('Blog', soup.title.text)
self.navbar_test(soup)
self.category_card_test(soup)
# 3-2. 포스트 목록 페이지를 새로 고침 했을 때,
response = self.client.get('/blog/')
soup = BeautifulSoup(response.content, 'html.parser')
# 3-3. 메인영역에 포스트 2개의 타이틀이 존재한다.
main_area = soup.find('div', id='main-area')
self.assertNotIn('아직 게시물이 없습니다.', main_area.text)
post_001_card = main_area.find('div', id='post-1')
self.assertIn(self.post_001.title, post_001_card.text)
self.assertIn(self.post_001.category.name, post_001_card.text)
post_002_card = main_area.find('div', id='post-2')
self.assertIn(self.post_002.title, post_002_card.text)
self.assertIn(self.post_002.category.name, post_002_card.text)
post_003_card = main_area.find('div', id='post-3')
self.assertIn(self.post_003.title, post_003_card.text)
self.assertIn('미분류', post_003_card.text)
self.assertIn(self.post_001.author.username.upper(), main_area.text)
self.assertIn(self.post_002.author.username.upper(), main_area.text)
self.assertIn(self.post_003.author.username.upper(), main_area.text)
def test_post_list_without_post(self):
Post.objects.all().delete()
self.assertEqual(Post.objects.count(), 0)
response = self.client.get('/blog/')
self.assertEqual(response.status_code, 200)
soup = BeautifulSoup(response.content, 'html.parser')
self.navbar_test(soup)
self.assertIn('Blog', soup.title.text)
# 2-2. 메인영역에 "아직 게시물이 없습니다." 라는 문구가 나온다.
main_area = soup.find('div', id='main-area')
self.assertIn('아직 게시물이 없습니다.', main_area.text)
def test_post_detail(self):
self.assertEqual(Post.objects.count(), 3)
# 1.2 그 포스트의 url은 '/blog/1/' 이다.
self.assertEqual(self.post_001.get_absolute_url(), '/blog/1/')
#.2. 첫 번째 포스트의 상세 페이지 테스트
# 2-1. 첫 번째 포스트의 url로 접근하면 정상적으로 작동한다. (status code : 200).
response = self.client.get(self.post_001.get_absolute_url())
self.assertEqual(response.status_code, 200)
soup = BeautifulSoup(response.content, 'html.parser')
# # 2-2. 포스트 목록 페이지와 똑같은 네비게이션 바가 있다.
self.navbar_test(soup)
# 2-3. 첫 번째 포스트의 제목이 웹 브라우저 탭 타이틀에 들어있다.
self.assertIn(self.post_001.title, soup.title.text)
# 2-4. 첫 번째 포스트의 제목이 포스트 영역에 있다.
main_area = soup.find('div', id='main-area')
post_area = main_area.find('div', id='post-area')
self.assertIn(self.post_001.title, post_area.text)
# # 2-5. 첫 번째 포스트의 작성자(author)가 포스트 영역에 있다. (아직 구현할 수 없음)
self.assertIn(self.user_trump.username.upper(), post_area.text)
# # 2-6. 첫 번째 포스트의 내용(content)이 포스트 영역에 있다.
self.assertIn(self.post_001.content, post_area.text)
base.html
<!DOCTYPE html>
{% load static %}
<html>
<head>
<title>{% block head_title %} Blog | 하도영 웹사이트 {% endblock %}</title>
<link href="{% static 'blog/bootstrap/bootstrap.min.css' %}" rel="stylesheet" type="text/css">
<!-- <link href="./practice.css" rel="stylesheet" type="text/css"> -->
<!-- 주석처리 키 ctrl + / -->
<script src="https://kit.fontawesome.com/c1d4d1ab30.js" crossorigin="anonymous"></script>
</head>
<body>
{% include 'blog/navbar.html' %}
<div class="container">
<!-- 블로그 리스트 페이지 만들기 강의 5:04 blog 글자 부분 container 클래스에 의해 do it django 와 같은 간격으로 맞춰짐 -->
<!-- 이 아래는 9:3, 좁을때는 8:4 로 나눌거임 -->
<div class="row my-3">
<div class="col-md-8 col-lg-9", id="main-area">
{% block main_area %}
{% endblock %}
</div>
<div class="col-md-4 col-lg-3">
<!-- Search widget-->
<div class="card mb-4">
<div class="card-header">Search</div>
<div class="card-body">
<div class="input-group">
<input class="form-control" type="text" placeholder="Enter search term..." aria-label="Enter search term..." aria-describedby="button-search" />
<button class="btn btn-primary" id="button-search" type="button">Go!</button>
</div>
</div>
<!-- Categories widget-->
<div class="card mb-4", id="categories-card">
<div class="card-header">Categories</div>
<div class="card-body">
<div class="row">
<ul>
{% for category in categories %}
<li>
<a href="#!">{{ category.name }} ({{ category.post_set.count }})</a>
</li>
{% endfor %}
<!-- views.py 에 def get_context_data(self, **kwargs): 를 참고한다. -->
<li>
<a href="#!">미분류 ({{ no_category_post.count }})</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
{% include 'blog/footer.html' %}
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct"
crossorigin="anonymous"></script>
</body>
</html>
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from .models import Post, Category
class PostList(ListView):
model = Post
# template_name = 'blog/post_list.html'
ordering = '-pk'
def get_context_data(self, **kwargs):
context = super(PostList, self).get_context_data()
context['categories'] = Category.objects.all()
context['no_category_post.count'] = Post.objects.filter(category=None).count()
# 미분류인 애들이 몇개인지 확인한다. filter기능을 이용해 none 인 애를 확인하고 count() 에 숫자를 담아 no_category_post.count에 넣어준다.
return context
class PostDetail(DetailView):
model = Post
template_name = 'blog/post_detail.html'
# def index(request):
# posts = Post.objects.all().order_by('-pk')
# # pk는 순서대로 -pk 는 역순으로 최신 쓰레드가 위로 나오도록 조회
# return render(
# request,
# 'blog/index.html',
# {
# 'posts': posts,
# }
# )
# def single_post_page(request, pk):
# post = Post.objects.get(pk=pk)
#
# return render(
# request,
# 'blog/single_page.html',
# {
# 'post': post,
# }
# )
post_list.html
{% extends 'blog/base.html' %}
{% block main_area %}
<h1> Blog </h1>
{% if post_list.exists %}
{% for p in post_list %}
<!-- Blog Post -->
<div class="card mb-4", id="post-{{ p.id }}">
{% if p.head_image %}
<img class="card-img-top" src="{{ p.head_image.url}}" alt="{{ p.title }}" />
{% else %}
<img class="card-img-top" src="https://picsum.photos/seed/{{ p.id }}/600/200" alt="{{ p.title }}" />
{% endif %}
<div class="card-body">
<!-- <div class="small text-muted">January 1, 2022</div>-->
{% if p.category %}
<span class="badge badge-secondary float-right">{{ p.category }} </span>
{% else %}
<span class="badge badge-secondary float-right">미분류</span>
{% endif %}
<h2 class="card-title h4">{{ p.title }}</h2>
{% if p.hook_text %}
<h5 class="text-muted">{{ p.hook_text }}</h5>
{% endif %}
<p class="card-text">{{ p.content | truncatewords:45 }}</p>
<a href="{{ p.get_absolute_url }}" class="btn btn-primary">Read more →</a>
</div>
<div class="card-footer text-muted">
Posted on {{ p.created_at }} by
<a href="#">{{ p.author | upper }}</a>
</div>
</div>
{% endfor %}
{% else %}
<h1> 아직 게시물이 없습니다. </h1>
{% endif %}
<!-- Pagination-->
<ul class="pagination justify-content-center my-4">
<li class="page-item">
<a class="page-link" href="#!">← Older</a>
</li>
<li class="page-item disabled">
<a class="page-link" href="#!">Newer →</a>
</li>
</ul>
{% endblock %}
답변 1
1
자답으로 찾았습니다^^;
views.py 부분에서
def get_context_data(self, **kwargs):
context = super(PostList, self).get_context_data()
context['categories'] = Category.objects.all()
context['no_category_post_count'] = Post.objects.filter(category=None).count()
return context
context['no_category_post.count'] = Post.objects.filter(category=None).count()
.count로 입력해서 () 카운트를 부르지 못했었습니다.