Django Girls Tutorial: Extensions
  • Django Girls Tutorial: Extensions
  • LANGS
  • contributing
  • Django Girls Tutorial: Extensions
    • Summary
    • Homework: Add Wagtail to your website
      • Change Website Homepage to Wagtail Blog Homepage
      • Wagtail Installation and Configuration
      • Adding the Homepage
      • wagtail_integration_adding_posts
    • Homework: Adding security to your website
    • Domain
    • Homework: add more to your website!
    • Homework: create comment model
    • Deploying to PythonAnywhere manually
    • optional_postgresql_installation
  • Tutorial Django Girls : Extensiones
    • Resumen
    • Tarea: Asegura tu sitio
    • Dominio
    • Tarea: Agregar mas a tu sitio web
    • Tarea: Crea un modelo de comentarios
    • optional_postgresql_installation
  • آموزش جنگوگرلز: فعالیت‌های اضافه
    • خلاصه
    • کار در خانه: وبسایت خود را امن‌تر کنید
    • دامین
    • کار در خانه: چیزهای بیشتری به وب‌سایت اضافه کنیم!
    • کار در خانه: ساختن مدل کامنت‌ها
    • انتشار دستی بر روی PythonAnywhere
    • README
  • Django Girls Tutorial: Extensions
    • Summary
    • 宿題: ウェブサイトをセキュアにする
    • ドメイン
    • 宿題: ウェブサイトにもっと機能を追加しよう!
    • 宿題:コメントモデルを作ろう
    • Deploying to PythonAnywhere manually
    • README
  • 장고걸스 튜토리얼 : 심화 (Django Girls Tutorial: Extensions)
    • 목차
    • 숙제: 안전한 웹사이트 만들기
    • 도메인 만들기
    • 숙제: 블로그 개선하기!
    • 숙제 : 댓글 모델 만들기
    • 파이썬애니웨어(PythonAnywhere) 수동 배포하기
    • optional_postgresql_installation
Powered by GitBook
On this page
  • Comment 모델 만들기
  • 데이터베이스에 새 모델 테이블 생성하기
  • 관리자 패널에 Comment 모델 등록하기
  • 댓글 보여주기
  • 댓글 작성하기
  • 댓글 관리하기

Was this helpful?

  1. 장고걸스 튜토리얼 : 심화 (Django Girls Tutorial: Extensions)

숙제 : 댓글 모델 만들기

Previous숙제: 블로그 개선하기!Next파이썬애니웨어(PythonAnywhere) 수동 배포하기

Last updated 1 year ago

Was this helpful?

지금까지 Post 모델만 있었죠. 독자들에게 피드백과 코멘트를 받을 수 있는 댓글을 만들어보면 어떨까요?

Comment 모델 만들기

blog/models.py 파일을 열어, 파일의 맨 마지막에 아래 코드를 추가해주세요.

class Comment(models.Model):
    post = models.ForeignKey('blog.Post', related_name='comments', on_delete=models.CASCADE)
    author = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(default=timezone.now)
    approved_comment = models.BooleanField(default=False)

    def approve(self):
        self.approved_comment = True
        self.save()

    def __str__(self):
        return self.text

각 필드 타입들에 대한 설명은 장고걸스 튜토리얼의 장에서 다뤘으니 다시 읽고 돌아와도 좋아요.

이번 장에서는 새로운 필드 타입을 써볼게요.

  • models.BooleanField - 참/거짓(true/false) 필드랍니다.

models.ForeignKey의 related_name 옵션은 Post 모델에서 댓글에 액서스할 수 있게 합니다.

데이터베이스에 새 모델 테이블 생성하기

자, 데이터베이스에 Comment 모델을 추가할 시간이에요. 그러려면 장고에게 모델 변경내용을 알려줘야 합니다. python manage.py makemigrations blog 명령어를 입력하세요.

    (myvenv) ~/djangogirls$ python manage.py makemigrations blog
    Migrations for 'blog':
      0002_comment.py:
        - Create model Comment

blog/migrations 디렉터리에 새로 마이그레이션 파일이 생성되었어요. 이제 python manage.py migrate blog 명령어로 변경내역을 적용합니다. 다음과 같은 출력이 보일 거예요.

    (myvenv) ~/djangogirls$ python manage.py migrate blog
    Operations to perform:
      Apply all migrations: blog
    Running migrations:
      Rendering model states... DONE
      Applying blog.0002_comment... OK

이제 Comment 모델이 데이터베이스 안에 생겼네요! 관리자 패널(admin panel)에서 Commnet 모델에 접근할 수 있다면 멋지겠죠?

관리자 패널에 Comment 모델 등록하기

관리자 패널에 모델을 등록하기 위해, blog/admin.py로 가서 아래 코드를 추가해주세요.

admin.site.register(Comment)

아래 코드 바로 밑에 추가하면 됩니다.

admin.site.register(Post)

파일 맨 처음에 Comment 모델을 import 하는 것을 잊지 마세요. 소스파일은 아래와 같은 내용이어야 합니다.

from django.contrib import admin
from .models import Post, Comment

admin.site.register(Post)
admin.site.register(Comment)

댓글 보여주기

blog/templates/blog/post_detail.html로 가서 {% endblock %}

태그 바로 전에 아래 코드를 추가하세요.

<hr>

<div data-gb-custom-block data-tag="for">

    <div class="comment">
        <div class="date">{{ comment.created_date }}</div>
        <strong>{{ comment.author }}</strong>
        <p>{{ comment.text|linebreaks }}</p>
    </div>

<div data-gb-custom-block data-tag="empty"></div>

    <p>No comments here yet :(</p>

</div>

자 이제 post_detail 페이지의 댓글을 읽을 수 있어요.

좀 더 이쁘게 보이면 좋겠어요. static/css/blog.css파일을 열어 css 코드를 추가해보세요.

.comment {
    margin: 20px 0px 20px 20px;
}

post_list 페이지에서 각 글마다 달린 댓글 개수도 보여줍시다. blog/templates/blog/post_list.html에 아래 코드를 추가해주세요.

<a href="

<div data-gb-custom-block data-tag="url" data-0='post_detail'></div>

">Comments: {{ post.comments.count }}</a>

이제 아래와 같은 코드가 될 거에요.


<div data-gb-custom-block data-tag="extends" data-0='blog/base.html'></div>

<div data-gb-custom-block data-tag="block">

    

<div data-gb-custom-block data-tag="for">

        <div class="post">
            <div class="date">
                {{ post.published_date }}
            </div>
            <h1><a href="

<div data-gb-custom-block data-tag="url" data-0='post_detail'></div>">{{ post.title }}</a></h1>
            <p>{{ post.text|linebreaksbr }}</p>
            <a href="<div data-gb-custom-block data-tag="url" data-0='post_detail'></div>">Comments: {{ post.comments.count }}</a>
        </div>
    </div>

</div>

댓글 작성하기

방문자는 댓글을 읽을 수 있지만, 직접 댓글을 남길 수는 없어요. 댓글을 작성할 수 있게 만들어 봅시다.

blog/forms.py파일의 맨 끝에 아래 코드를 추가하세요.

class CommentForm(forms.ModelForm):

    class Meta:
        model = Comment
        fields = ('author', 'text',)

파일 맨 처음에 Comment 모델을 import 하는 것을 잊지 마세요.

아래 코드를 찾아

from .models import Post

이렇게 수정하세요.

from .models import Post, Comment

다음으로 blog/templates/blog/post_detail.html 파일에서 {% for comment in post.comments.all %} 전에 아래 코드를 추가해주세요.

<a class="btn btn-default" href="<div data-gb-custom-block data-tag="url" data-0='add_comment_to_post'></div>

">Add comment</a>

post_detail 페이지로 가면 에러가 뜰 거에요.

어떻게 고쳐야하는지 알고 있을 거에요! blog/urls.py 파일에서 urlpatterns에 새 패턴을 추가해야죠.

url(r'^post/(?P<pk>\d+)/comment/$', views.add_comment_to_post, name='add_comment_to_post'),

페이지를 새로고침하면 또 에러가 보일 거에요!

에러를 해결하려면 blog/views.py 파일에서 새로운 뷰를 추가해야해요.

def add_comment_to_post(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.save()
            return redirect('post_detail', pk=post.pk)
    else:
        form = CommentForm()
    return render(request, 'blog/add_comment_to_post.html', {'form': form})

이번에도 파일 맨 처음에 CommentForm 을 import 하는 것을 잊지 마세요.

from .forms import PostForm, CommentForm

이제 post_detail 페이지로 가보면, "Add comment" 버튼을 확인할 수 있을 거에요.

하지만, 버튼을 끌릭하면 이런 게 보이겠죠.

이 에러는 뷰에서 지정된 템플릿이 없다는 에러에요. blog/templates/blog/ 경로에 add_comment_to_post.html이라는 새 파일을 만들고 아래 코드를 작성하세요.


<div data-gb-custom-block data-tag="extends" data-0='blog/base.html'></div>

<div data-gb-custom-block data-tag="block">

    <h1>New comment</h1>
    <form method="POST" class="post-form">

<div data-gb-custom-block data-tag="csrf_token"></div>

        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Send</button>
    </form>

</div>

와! 이제 내 블로그 글을 읽은 사람들이 댓글을 남길 수 있게 되었네요!

댓글 관리하기

현재 블로그에 남겨진 모든 댓글들이 post_detail 페이지에 보이네요. 블로그 관리자가 댓글을 승인하거나 삭제할 수 있는 기능이 필요하겠죠. 이제 이 기능을 만들어 봅시다.

blog/templates/blog/post_detail.html 파일에서 아래 코드를 찾아


<div data-gb-custom-block data-tag="for">

    <div class="comment">
        <div class="date">{{ comment.created_date }}</div>
        <strong>{{ comment.author }}</strong>
        <p>{{ comment.text|linebreaks }}</p>
    </div>

<div data-gb-custom-block data-tag="empty"></div>

    <p>No comments here yet :(</p>

</div>

이렇게 바꾸세요.


<div data-gb-custom-block data-tag="for">

    

<div data-gb-custom-block data-tag="if">

    <div class="comment">
        <div class="date">
            {{ comment.created_date }}
            

<div data-gb-custom-block data-tag="if">

                <a class="btn btn-default" href="

<div data-gb-custom-block data-tag="url" data-0='comment_remove'></div>"><span class="glyphicon glyphicon-remove"></span></a>
                <a class="btn btn-default" href="<div data-gb-custom-block data-tag="url" data-0='comment_approve'></div>"><span class="glyphicon glyphicon-ok"></span></a>
            </div>

        </div>
        <strong>{{ comment.author }}</strong>
        <p>{{ comment.text|linebreaks }}</p>
    </div>
    

</div>

<div data-gb-custom-block data-tag="empty"></div>

    <p>No comments here yet :(</p>

</div>

NoReverseMatch 예외가 뜰 텐데요. 이를 comment_remove와 comment_approve 패턴에 매칭되는 url이 없기 때문이에요.

에러를 해결하려면 blog/urls.py 에 url 패턴을 추가해주세요.

url(r'^comment/(?P<pk>\d+)/approve/$', views.comment_approve, name='comment_approve'),
url(r'^comment/(?P<pk>\d+)/remove/$', views.comment_remove, name='comment_remove'),

이제 AttributeError 에러가 또 보일 거에요. 에러를 해결하기 위해, blog/views.py 에 뷰를 추가해주세요.

@login_required
def comment_approve(request, pk):
    comment = get_object_or_404(Comment, pk=pk)
    comment.approve()
    return redirect('post_detail', pk=comment.post.pk)

@login_required
def comment_remove(request, pk):
    comment = get_object_or_404(Comment, pk=pk)
    comment.delete()
    return redirect('post_detail', pk=comment.post.pk)

파일 맨 처음에 Comment를 import하는 것을 잊지 않았겠죠.

from .models import Post, Comment

모든 것이 잘 작동되네요! 하지만 마지막 한 가지가 남았어요. 현재 post_list 페이지에서는 등록된 모든 댓글의 개수가 보이는데요. 승인된 댓글의 개수만 보이게 수정해봅시다.

blog/templates/blog/post_list.html파일에서 아래 코드를

<a href="

<div data-gb-custom-block data-tag="url" data-0='post_detail'></div>">Comments: {{ post.comments.count }}</a>

다음과 같이 수정해주세요.

<a href="<div data-gb-custom-block data-tag="url" data-0='post_detail'></div>">Comments: {{ post.approved_comments.count }}</a>

그리고 blog/models.py 파일에서 Post 모델에 아래 메서드를 추가해주세요.

def approved_comments(self):
    return self.comments.filter(approved_comment=True)

드디어 댓글 기능을 모두 만들었어요! 함께 축하해요. :-)

커맨드 라인에서 python manage.py runserver를 입력하고 브라우저에서 를 열어보세요. Comment 리스트가 보이고, 댓글을 추가 삭제할 수 있을 거예요. 주저하지 말고 댓글을 가지고 놀아보세요.

Django 모델
http://127.0.0.1:8000/admin/
NoReverseMatch
AttributeError
AddComment
TemplateDoesNotExist