장고 - 게시판 댓글 기능 적용

ex) 게시판 프로젝트(board_project)

1. 특정 페이지에서 댓글 템플릿 연동

  • 댓글 목록의 template 따로 생성 (댓글 부분 페이지네이션 필요하기 때문)
  • 경로 : templates > board > comment_list.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <table class="table table-striped">
    <thead>
    <tr>
    <th colspan="3" class="align-left">댓글 목록</th>
    </tr>
    </thead>
    {% for comment in comments %}
    <tr>
    <td>{{comment.text}}</td>
    <td>{{comment.author.username}}</td>
    <td>{{comment.created}}</td>
    </tr>
    {% endfor %}
    </table>

2. 게시판 상세 페이지에서 댓글 목록 삽입 부분 작성

  • 경로 : templates > board > document_detail.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    {% extends 'base.html' %}

    {% block content %}

    {{object.title}} {{object.text}} {{object.image.url}} {{object.author.username}} <br>
    <hr>
    <form action="{% url 'board:comment_create' object.id %}" method="post">
    {% csrf_token %}
    {{comment_form.as_p}}
    <input type="submit" value="Comment" class="btn btn-outline-primary">
    </form>

    <!-- 댓글 목록이 삽입될 부분 -->
    <div id="docs_comment_list_area">
    {% include 'board/comment_list.html' %}
    </div>

    {% endblock %}

3. 댓글 생성/수정/삭제 함수 구현

  • 경로 : board_project > board > views.py

    • 댓글 생성(comment_create)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      def comment_create(request, document_id):
      document = get_object_or_404(Document, pk=document_id)
      comment_form = CommentForm(request.POST)
      comment_form.instance.author_id = request.user.id
      comment_form.instance.document_id = document_id
      if comment_form.is_valid():
      comment = comment_form.save()

      # return redirect(reverse('board:detail', args=[document_id]))
      return redirect(document)
    • 댓글 수정(comment_update)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      def comment_update(request, comment_id):
      comment = get_object_or_404(Comment, pk=comment_id)
      document = get_object_or_404(Document, pk=comment.document.id)
      if request.user != comment.author:
      messages.warning(request, "권한 없음")
      return redirect(document)
      if request.method == "POST":
      form = CommentForm(request.POST, request.FILES, instance=comment)
      if form.is_valid():
      form.save()
      return redirect(document)
      else:
      form = CommentForm(instance=comment)
      return render(request, 'board/comment/comment_update.html', {'form':form})
    • 댓글 삭제(comment_delete)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      def comment_delete(request, comment_id):
      comment = get_object_or_404(Comment, pk=comment_id)
      document = get_object_or_404(Document, pk=comment.document.id)
      if request.user != comment.author and not request.user.is_staff and request.user != document.author:
      messages.warning(request, "권한 없음")
      return redirect(document)

      if request.method == "POST":
      comment.delete()
      return redirect(document)
      else:
      return render(request, 'board/comment/comment_delete.html', {'object':comment})

4. 댓글 생성/수정/삭제 페이지 url 경로 설정

  • 경로 : board_project > board > urls.py
    1
    2
    3
    4
    5
    urlpatterns = [
    path('comment/create/<int:document_id>', comment_create, name='comment_create'),
    path('comment/update/<int:comment_id>', comment_update, name='comment_update'),
    path('comment/delete/<int:comment_id>', comment_delete, name='comment_delete'),
    ]

5. 댓글 수정/삭제 템플릿 파일 생성 및 작성

  • 경로 : templates > board > comment

    • comment_delete.html 생성 (댓글 삭제 페이지)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
              {% extends 'base.html' %}
      {% block content %}
      <form action="" method="post">
      {% csrf_token %}
      {{form.as_p}}
      <input type="submit" value="Update" class="btn btn-outline-warning">
      </form>
      {% endblock %}1) messages 클래스 호출
          - from django.contrib import messages
      2) request한 유저와 comment 작성자 동일 인물 아닐 시, 메시지 경고
          - if request.user != comment.author:
              messages.warning(request, "권한 없음")
    • comment_update.h1) messages 클래스 호출

    • from django.contrib import messages
      2) request한 유저와 comment 작성자 동일 인물 아닐 시, 메시지 경고
    • if request.user != comment.author:
      messages.warning(request, “권한 없음”)이지))
      1
      2
      3
      4
      5
      6
      7
      8
      9
      {% extends 'base.html' %}
      {% block content %}
      <form action="" method="post">
      <div class="alert alert-danger">Do you want to delete {{object}}?</div>
      {% csrf_token %}
      {{form.as_p}}
      <input type="submit" value="Delete Confirm" class="btn btn-outline-danger">
      </form>
      {% endblock %}

6. 관리자 사이트에 댓글 조회 및 수정 기능 적용

  • 관리자페이지 커스터마이징
  • 경로 : board > admin.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class CommentInline(admin.TabularInline):
    model = Comment
    class DocumentOption(admin.ModelAdmin):
    list_display = ['id', 'author', 'title', 'text', 'slug', 'created', 'updated']
    prepopulated_fields = {'slug':('title',)}
    inlines = [CommentInline] # 추가

    admin.site.regiser(Document, DocumentOption)
    admin.site.register(Comment)