inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Do It! 장고+부트스트랩: 파이썬 웹개발의 정석

update_post_url에서 오류가 납니다

392

ium1018

작성한 질문수 1

0

 

The view blog.views.view didn't return an HttpResponse object. It returned None instead.
이런 오류가 발생하는데 이것저것 검색해봐도 해결이 안돼서 질문하게 되었습니다
오타없이 한거 같은데 어떤 부분에서 에러가 나는지 도무지 감을 못잡겠습니다

python aws bootstrap javascript tdd docker django HTML/CSS

답변 3

1

SungYong Lee

PostUpdate 클래스에서 raise PermissionDenied 라고 해야 하는데, raise를 빼놓으신게 눈에 들어오네요. 

다른 이유일수도 있겠지만.

0

ium1018

알려주신대로 수정했더니 제대로 결과가 나왔습니다 감사합니다!!!

0

SungYong Lee

urls.py

views.py

tests.py

모두 보여주세요. 현재 정보로는 판단하기가 어렵습니다. 

0

ium1018

update부분 지우고 강의들으면서 다시 해봤는데

views.py 에서 dispatch 여기 추가하니까 처음 글을 올리게 된 에러가 발생하는것 같습니다

그전까지는 강의에서 보여주신대로 에러나 ok나 똑같이 나왔었습니다

tests.py


from django.test import TestCase, Client
from django.contrib.auth.models import User
from bs4 import BeautifulSoup
from .models import Post, Category, Tag


class TestView(TestCase):
def setUp(self):
self.client = Client()
self.user_apple = User.objects.create_user(
username='apple',
password='somepassword'
)

self.user_grape = User.objects.create_user(
username='grape',
password='somepassword'
)
self.user_grape.is_staff = True
self.user_grape.save()

self.category_programming = Category.objects.create(
name='programming', slug='programming'
)
self.category_music = Category.objects.create(
name='music', slug='music'
)

self.tag_python_kor = Tag.objects.create(
name='파이썬 공부', slug = '파이썬 공부'
)
self.tag_python = Tag.objects.create(
name='python', slug='python'
)
self.tag_hello = Tag.objects.create(
name='hello', slug='hello'
)

self.post_001 = Post.objects.create(
title='첫번째 포스트 입니다',
content='Hello, World. We are the World',
category=self.category_programming,
author=self.user_apple
)
self.post_001.tags.add(self.tag_hello)

self.post_002 = Post.objects.create(
title='두번째 포스트 입니다',
content='저는 커피를 좋아합니다',
category=self.category_music,
author=self.user_grape
)
self.post_003 = Post.objects.create(
title='세번째 포스트 입니다',
content='Category가 없을수도 있죠',
author=self.user_grape
)
self.post_003.tags.add(self.tag_python_kor)
self.post_003.tags.add(self.tag_python)

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='Django_Practice')
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)

response = self.client.get('/blog/')
self.assertEqual(response.status_code, 200)
soup = BeautifulSoup(response.content, 'html.parser')

self.assertIn('Blog', soup.title.text)

self.navbar_test(soup)
self.category_card_test(soup)

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)
self.assertIn(self.tag_hello.name, post_001_card.text)
self.assertNotIn(self.tag_python.name, post_001_card.text)
self.assertNotIn(self.tag_python_kor.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)
self.assertNotIn(self.tag_hello.name, post_002_card.text)
self.assertNotIn(self.tag_python.name, post_002_card.text)
self.assertNotIn(self.tag_python_kor.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.assertNotIn(self.tag_hello.name, post_003_card.text)
self.assertIn(self.tag_python.name, post_003_card.text)
self.assertIn(self.tag_python_kor.name, 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)

def test_post_list_without_posts(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)

main_area = soup.find('div', id='main-area')
self.assertIn('아직 게시물이 없습니다', main_area.text)

def test_post_detail(self):
self.assertEqual(Post.objects.count(), 3)
self.assertEqual(self.post_001.get_absolute_url(), '/blog/1/')

response = self.client.get(self.post_001.get_absolute_url())
self.assertEqual(response.status_code, 200)

soup = BeautifulSoup(response.content, 'html.parser')
self.navbar_test(soup)
self.category_card_test(soup)

self.assertIn(self.post_001.title, soup.title.text)

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)
self.assertIn(self.post_001.category.name, post_area.text)

self.assertIn(self.user_apple.username.upper(), post_area.text)
self.assertIn(self.post_001.content, post_area.text)

self.assertIn(self.tag_hello.name, post_area.text)
self.assertNotIn(self.tag_python.name, post_area.text)
self.assertNotIn(self.tag_python_kor.name, post_area.text)

def test_category_page(self):
response = self.client.get(self.category_programming.get_absolute_url())
self.assertEqual(response.status_code, 200)

soup = BeautifulSoup(response.content, 'html.parser')
self.navbar_test(soup)
self.category_card_test(soup)

main_area = soup.find('div', id='main-area')
self.assertIn(self.category_programming.name, main_area.h1.text)
self.assertIn(self.category_programming.name, main_area.text)
self.assertIn(self.post_001.title, main_area.text)
self.assertNotIn(self.post_002.title, main_area.text)
self.assertNotIn(self.post_003.title, main_area.text)

def test_tag_page(self):
response = self.client.get(self.tag_hello.get_absolute_url())
self.assertEqual(response.status_code, 200)
soup = BeautifulSoup(response.content, 'html.parser')

self.navbar_test(soup)
self.category_card_test(soup)

self.assertIn(self.tag_hello.name, soup.h1.text)
main_area = soup.find('div', id='main-area')
self.assertIn(self.tag_hello.name, main_area.text)

self.assertIn(self.post_001.title, main_area.text)
self.assertNotIn(self.post_002.title, main_area.text)
self.assertNotIn(self.post_003.title, main_area.text)

def test_create_post_without_login(self):
response = self.client.get('/blog/create_post/')
self.assertNotEqual(response.status_code, 200)

def test_create_post_with_login(self):
self.client.login(username='apple', password='somepassword')
response = self.client.get('/blog/create_post/')
self.assertNotEqual(response.status_code, 200)

self.client.login(username='grape', password='somepassword')
response = self.client.get('/blog/create_post/')
self.assertEqual(response.status_code, 200)

soup = BeautifulSoup(response.content, 'html.parser')
self.assertEqual('Create Post - Blog', soup.title.text)
main_area = soup.find('div', id='main-area')
self.assertIn('Create a New Post', main_area.text)

self.client.post(
'/blog/create_post/',
{
'title': 'Post Form 만들기',
'content': 'Post Form 페이지를 만듭시다'
}
)

last_post = Post.objects.last()
self.assertEqual(last_post.title, 'Post Form 만들기')
self.assertEqual(last_post.author.username, 'grape')
self.assertEqual(last_post.content, 'Post Form 페이지를 만듭시다')

def test_update_post(self):
update_post_url = f'/blog/update_post/{self.post_003.pk}/'

# not login
response = self.client.get(update_post_url)
self.assertNotEqual(response.status_code, 200)

# login, but not author
self.assertNotEqual(self.post_003.author, self.user_apple)
self.client.login(username='apple', password='somepassword')
response = self.client.get(update_post_url)
self.assertNotEqual(response.status_code, 200)

# login and author
self.assertEqual(self.post_003.author, self.user_grape)
self.client.login(username='grape', password='somepassword')
response = self.client.get(update_post_url)
self.assertEqual(response.status_code, 200)
soup = BeautifulSoup(response.content, 'html.parser')

self.assertEqual('Edit Post - Blog', soup.title.text)
main_area = soup.find('div', id='main-area')
self.assertIn('Edit Post', main_area.text)

response = self.client.post(
update_post_url,
{
'title': '세번째 포스트를 수정했습니다',
'content': '안녕 세계? 우리는 하나!',
'category': self.category_music.pk
},
follow=True
)
soup = BeautifulSoup(response.content, 'html.parser')
main_area = soup.find('div', id='main-area')
self.assertIn('세번째 포스트를 수정했습니다', main_area.text)
self.assertIn('안녕 세계? 우리는 하나!', main_area.text)
self.assertIn(self.category_music.name, main_area.text)

views.py

from django.core.exceptions import PermissionDenied
from django.shortcuts import render, redirect, HttpResponse
from django.template import loader
from django.views.generic import ListView, DetailView, CreateView, UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from .models import Post, Category, Tag




class PostList(ListView):
model = Post
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()
return context


class PostDetail(DetailView):
model = Post

def get_context_data(self, **kwargs):
context = super(PostDetail, self).get_context_data()
context['categories'] = Category.objects.all()
context['no_category_post_count'] = Post.objects.filter(category=None).count()
return context


class PostCreate(LoginRequiredMixin, UserPassesTestMixin, CreateView):
model = Post
fields = ['title', 'hook_text', 'content', 'head_image', 'file_upload', 'category']

def test_func(self):
return self.request.user.is_superuser or self.request.user.is_staff

def form_valid(self, form):
current_user = self.request.user
if current_user.is_authenticated and (current_user.is_staff or current_user.is_superuser):
form.instance.author = current_user
return super(PostCreate, self).form_valid(form)
else:
return redirect('/blog/')


class PostUpdate(LoginRequiredMixin, UpdateView):
model = Post
fields = ['title', 'hook_text', 'content', 'head_image', 'file_upload', 'category']
template_name = 'blog/post_update_form.html'

def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated and request.user == self.get_object().author:
return super(PostUpdate, self).dispatch(request, *args, **kwargs)
else:
PermissionDenied


def category_page(request, slug):
if slug == 'no_category':
category = '미분류'
post_list = Post.objects.filter(category=None)
else:
category = Category.objects.get(slug=slug)
post_list = Post.objects.filter(category=category)

return render(
request,
'blog/post_list.html',
{
'post_list': post_list,
'categories': Category.objects.all(),
'no_category_post_count': Post.objects.filter(category=None).count(),
'category': category
}
)


def tag_page(request, slug):
tag = Tag.objects.get(slug=slug)
post_list = tag.post_set.all()

return render(
request,
'blog/post_list.html',
{
'post_list': post_list,
'categories': Category.objects.all(),
'no_category_post_count': Post.objects.filter(category=None).count(),
'tag': tag
}
)

 

urls.py

from django.urls import path
from . import views

urlpatterns = [
path('update_post/<int:pk>/', views.PostUpdate.as_view()),
path('create_post/', views.PostCreate.as_view()),
path('tag/<str:slug>/', views.tag_page),
path('category/<str:slug>/', views.category_page),
path('<int:pk>/', views.PostDetail.as_view()),
path('', views.PostList.as_view()),
]

0

SungYong Lee

현재 주신 정보만으로는 원인을 찾기가 어렵네요. 어떤 코드에서 에러가 나는지, 보여주시거나, 혹은 깃허브 리포지토리를 공유해주시면 더 쉽게 알려드릴 수 있습니다. 

0

ium1018

테스트를 해보면 이렇게 에러가 뜹니다

 

로그인 오류

0

88

2

docker-compose down 안되는 현상

0

206

2

url pattern관련 문의

0

198

2

오류

0

255

1

doitdjango 블로그 게시판 작동 오류

1

301

1

구글 로그인 오류 .

0

463

2

makemigrations 을 했는데 aws lightsail에서

0

205

1

안녕하세요 강사님,

0

403

2

맥북 프로 14 가상화 확인

0

438

2

테스트 코드 오류

0

389

2

섹션 6-2 알림 내용 중 링크가 잘못되어 있네요.

0

282

2

장고 개발 준비.

0

407

2

Mac

0

321

1

TDD 통과 했지만, 실제 웹에서 작동하지 않습니다.

0

375

1

summernote를 적용하고 이미지를 업로그하면 모바일에서 볼때는 이미지가 크게 나오는데 어떻게 해야 되나요?

0

916

2

python manage.py test 를 돌리면 allauth.socialaccount.models.SocialApp.DoesNotExist 에러가 뜹니다.

1

1696

2

self.client.post에 글이 생성되지않습니다

0

339

1

Nginx 설정 이후 개발용 도커 컨테이너 실행

0

552

1

UpdateView - 포스트 수정 페이지 만들기 에서 질문이 있습니다.

0

405

1

from .models import Question

0

1221

1

파이참 장고 인식 불가 문제

0

1006

2

배포용 도커 컨테이너 실행이 안됩니다

0

717

1

docker-compose exec web manage.py migrate

0

555

1

search_info가 안나옵니다..

0

361

2