본문 바로가기

멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차/WEB

2/18 금

728x90

앜 불금!!!!! 🐱‍🏍🐱‍👤

 

오늘은 어제 추가했던 게시판 글 상세보기 페이지 하단에 넣었던 버튼들의 기능을 실현시킨다.

 

오후 3시 반 정도에 게시판 구현을 마무리 짓고, 편성된 조별로 소회의실에서 나머지 시간을 보냈다.

팀원들과 아이스브레이킹, 웹 프로젝트 주제 선정, 스토리 보드 작성함~

 

월요일에는 인터페이스 개발 수업에 대한 첫 평가(필답)가 있을 예정!

주말 동안 여태 배우며 정리했던 내용들을 다시 점검하고, 게시판 기능을 마저 구현해야 한다.

 

1. 리스트로 돌아가기 버튼

JavaScript event 방식(Delegation Model)으로 처리

↓detail.html↓

    <button class="btn btn-secondary" onclick="to_list()">리스트로 돌아가기</button>

↓menu_btn.js↓

function to_list() {
    document.location.href = '/bbs/list/'
}

2. 삭제 버튼

 

템플릿 태그로 감싼 initial.id를 span 엘리먼트 안에 넣고 id를 부여함. 삭제 버튼에 event handler 넣기

↓detail.html↓

{% extends 'base.html' %}
{% load bootstrap4 %}

{% block html_header %}
<script src="/static/js/menu_btn.js"></script>
{% endblock %}

{% block html_body %}
<div class="container">
    <h1>상세보기</h1>
    글 번호 : <span id="post_id">{{ detail_form.initial.id }}</span>
    글 제목 : {{ detail_form.initial.b_title }}
    <br>
    {% bootstrap_form detail_form %}
    <br>
    <button class="btn btn-secondary" onclick="to_list()">리스트로 돌아가기</button>
    <button class="btn btn-primary">수정</button>
    <button class="btn btn-danger" onclick="delete_post()">삭제</button>
    <button class="btn btn-warning" onclick="b_like()">좋아요</button>
</div>
{% endblock %}

정말 삭제할지 경고창으로 확인 후 쿼리 스트링으로 게시글 id을 문자열로 가져와 /bbd/delete/post_id 창으로 이동

↓menu_btn.js↓

function delete_post() {
    // alert($('#post_id').text())
    let result = confirm("정말 삭제할까요?")
    if(result) {
        let queryString = "?post_id=" + $('#post_id').text()
        document.location.href = '/bbs/delete/' + queryString
    }
}

↓bbs/urls.py↓

path('delete/', views.b_delete, name='b_delete'),

GET 방식으로 post_id와 이에 해당하는 Board 객체를 가져와서 삭제하고 게시판으로 redirect

↓views.py↓

def b_delete(request):
    post_id = request.GET['post_id']
    post = get_object_or_404(Board, pk=post_id)
    post.delete()
    return redirect('bbs:b_list')

3. 좋아요 버튼

↓detail.html↓

    <button class="btn btn-warning" onclick="like_post()">좋아요</button>

↓menu_btn.js↓

function like_post() {
        let queryString = "?post_id=" + $('#post_id').text()
        document.location.href = '/bbs/like/' + queryString
}

↓bbs/urls.py↓

    path('like/', views.b_like, name='b_like'),

GET 방식으로 post_id와 이에 해당하는 Board 객체를 가져와서 좋아요 수에 1을 더하고 저장.

글 상세보기 페이지에 만들어둔 Form으로 가져온 객체를 표현함

↓views.py↓

def b_like(request):
    post_id = request.GET['post_id']
    post = get_object_or_404(Board, pk=post_id)
    post.b_like_count += 1
    post.save()

    board_detail_form = BoardDetailForm(instance=post)
    context = {
        'detail_form': board_detail_form
    }
    return render(request, 'bbs/detail.html', context)

4. 댓글 등록

 

게시글 상세보기 함수에 댓글 항목을 추가

↓views.py↓

def b_detail(request, board_id):
    post = get_object_or_404(Board, pk=board_id)
    board_detail_form = BoardDetailForm(instance=post) # post를 가지고 Model Form 객체를 만듦
    comments = post.comment_set.all().order_by('-id') # 모든 댓글을 발행 역순으로 나열하라
    context = {
        'detail_form': board_detail_form,
        'comments': comments
    }
    return render(request, 'bbs/detail.html', context)

block html_body 안에 댓글 양식 입력

↓detail.html↓

        <tbody>
            <tr>
                <td>강감찬</td>
                <td>더 깎아주세요!</td>
                <td><button class="btn btn-danger">삭제</button></td>
            </tr>
        </tbody>

http://127.0.0.1:8000/bbs/4/detail/

HTML로 직접 댓글을 입력하는 게 아닌 상세보기 페이지에서 입력할 수 있도록 변경

↓detail.html↓

{% extends 'base.html' %}
{% load bootstrap4 %}

{% block html_header %}
<script src="/static/js/menu_btn.js"></script>
{% endblock %}

{% block html_body %}
<div class="container">
    <h1>상세보기</h1>
    글 번호 : <span id="post_id">{{ detail_form.initial.id }}</span>
    글 제목 : {{ detail_form.initial.b_title }}
    <br>
    {% bootstrap_form detail_form %}
    <br>
{#    <a href="{% url 'bbs:b_list' %}" class="btn btn-secondary">리스트로 돌아가기</a>#}
    <button class="btn btn-success" onclick="to_list()">리스트로 돌아가기</button>
    <button class="btn btn-primary">수정</button>
    <button class="btn btn-danger" onclick="delete_post()">삭제</button>
    <button class="btn btn-warning" onclick="like_post()">좋아요</button>
</div>

<br><br>
<div class="container">
    <h3>댓글</h3>
    <label for="c_name">이름</label>
    <input type="text" class="form-control w-25" id="c_name">

    <label for="c_content">내용</label>
    <input type="text" class="form-control w-50" id="c_content">
    <br>
    <button type="button" class="btn btn-info" onclick="create_comment()">댓글 등록</button>

    <table class="table table-hover">
        <thead class="thread-dark">
            <tr>
                <th scope="col">댓글 작성자</th>
                <th scope="col">댓글 내용</th>
                <th scope="col">삭제</th>
            </tr>
        </thead>
        <tbody>
            {% for comment in comments %}
            <tr>
                <td>{{ comment.c_author }}</td>
                <td>{{ comment.c_content }}</td>
                <td><button class="btn btn-danger">삭제</button></td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</div>
<br><br><br>
{% endblock %}

 

↓menu_btn.js↓

function create_comment() {
    $.ajax({
        async: true,
        url: "/bbs/createComment/",
        type: 'GET',
        data: {
            board_id: $('#post_id').text(),
            comment_author: $('#c_name').val(),
            comment_content: $('#c_content').val()
        },
        dataType: 'json',
        timeout: 3000,
        success: function (result) {
            // alert('AJAX 성공')
            let tr = $("<tr></tr>")
            let author_td = $("<td></td>").text(result['c_author'])
            let content_td = $("<td></td>").text(result['c_content'])
            let btn_td = $("<td></td>")
            let btn = $("<button></button>").text("삭제").addClass("btn btn-danger")
            btn_td.append(btn)
            tr.append(author_td)
            tr.append(content_td)
            tr.append(btn_td)
            $('tbody').prepend(tr)
        },
        error: function () {
            alert('뭔가 이상해요!')
        }
    })
}

↓bbs/urls.py↓

path('createComment/', views.create_comment, name='create_comment'),

댓글 등록 버튼을 누르면 create_comment() 함수가 Ajax로 data가 호출되기 때문에 HttpResponse 객체가 아닌 JsonResponse(상단에서 import)로 나가야 함

↓views.py↓

from django.shortcuts import render, redirect, get_object_or_404
from bbs.models import Board, Comment
from bbs.forms import BoardForm, BoardDetailForm
from django.http import JsonResponse

def b_list(request):
    posts = Board.objects.all().order_by('-id')
    context = {
        'posts': posts
    }
    return render(request, 'bbs/list.html', context)

def b_create(request):
    # request 방식이 GET or POST인지 구분해서 처리
    # GET 방식이면 빈 입력 상자를 출력하고,
    if request.method == 'GET':

        board_form = BoardForm()
        context = {
           'my_form': board_form
        }
        return render(request, 'bbs/create.html', context)
    # POST 방식이면 client가 입력된 데이터를 이용해서 DB 처리
    else:
        board_form = BoardForm(request.POST) # client가 입력된 데이터를 가지고 있는 ModelForm

        if board_form.is_valid():
            board_form.save()
            # 입력 받은 값 이외에 다른 컬럼의 값을 지정해서 사용할 때(좋아요 개수 10)
            # new_post = board_form.save(commit=False)
            # new_post.b_like_count = 10
            # new_post.save()
            return redirect('bbs:b_list')

def b_detail(request, board_id):
    post = get_object_or_404(Board, pk=board_id)
    board_detail_form = BoardDetailForm(instance=post) # post를 가지고 Model Form 객체를 만듦
    comments = post.comment_set.all().order_by('-id') # 모든 댓글을 발행 역순으로 나열하라
    context = {
        'detail_form': board_detail_form,
        'comments': comments
    }
    return render(request, 'bbs/detail.html', context)

def b_delete(request):
    post_id = request.GET['post_id']
    post = get_object_or_404(Board, pk=post_id)
    post.delete()
    return redirect('bbs:b_list')

def b_like(request):
    post_id = request.GET['post_id']
    post = get_object_or_404(Board, pk=post_id)
    post.b_like_count += 1
    post.save()

    board_detail_form = BoardDetailForm(instance=post)
    context = {
        'detail_form': board_detail_form
    }
    return render(request, 'bbs/detail.html', context)

def create_comment(request):
    comment = Comment()
    comment.c_author = request.GET['comment_author']
    comment.c_content = request.GET['comment_content']
    comment.board_id = request.GET['board_id']
    comment.save()
    # AJAX로 호출되었기 때문에 그 결과가 HttpResponse 객체가 아닌 JsonResponse로 나가야 함!
    # JsonResponse(결과JSON,json_dumps_params={'ensure_ascii': True})
    return JsonResponse({
        'c_id': comment.id,
        'c_author': comment.c_author,
        'c_content': comment.c_content
    },
                        json_dumps_params={'ensure_ascii': True})

5. 댓글 삭제

↓menu_btn.js↓

function new_post() {
    document.location.href = '/bbs/create/'
}

function to_list() {
    document.location.href = '/bbs/list/'
}

function delete_post() {
    // alert($('#post_id').text())
    let result = confirm("정말 삭제할까요?")
    if(result) {
        let queryString = "?post_id=" + $('#post_id').text()
        document.location.href = '/bbs/delete/' + queryString
    }
}

function like_post() {
        let queryString = "?post_id=" + $('#post_id').text()
        document.location.href = '/bbs/like/' + queryString
}

function create_comment() {
    $.ajax({
        async: true,
        url: "/bbs/createComment/",
        type: 'GET',
        data: {
            board_id: $('#post_id').text(),
            comment_author: $('#c_name').val(),
            comment_content: $('#c_content').val()
        },
        dataType: 'json',   // 서버 프로그램이 결과로 돌려주는 값은 JSON
        timeout: 3000,
        success: function(result) {
            let tr = $("<tr></tr>").attr('id','comment_' + result['c_id'])
            let author_td = $('<td></td>').text(result['c_author'])
            let content_td = $('<td></td>').text(result['c_content'])
            let btn_td = $('<td></td>')
            let btn = $('<button></button>').text('삭제').addClass('btn btn-danger')
            btn.on('click',function() {
                $.ajax({
                    async: true,
                    url: '/bbs/deleteComment/',
                    type: 'GET',
                    data: {
                        comment_id: result['c_id']
                    },
                    dataType: 'json',
                    timeout: 3000,
                    success: function() {
                        alert('댓글 삭제 성공!!')
                        $('#comment_' + result['c_id']).remove()
                    },
                    error: function() {
                        alert('댓글 삭제 실패!')
                    }
                })
            })
            btn_td.append(btn)
            tr.append(author_td)
            tr.append(content_td)
            tr.append(btn_td)
            $('tbody').prepend(tr)
        },
        error: function() {
            alert('뭔가 이상해요!')
        }
    })
}

↓bbs/urls.py↓

# bbs App의 URLConf(http://127.0.0.1:8000/bbs/)
from django.urls import path
from bbs import views

app_name = 'bbs'

urlpatterns = [
    # http://localhost::8000/bbs/list/
    path('list/', views.b_list, name='b_list'),
    # http://localhost::8000/bbs/create/
    path('create/', views.b_create, name='b_create'),
    # http://localhost::8000/bbs/<int:board_id>/detail/
    path('<int:board_id>/detail/', views.b_detail, name='b_detail'),
    # http://localhost::8000/bbs/delete/#post_id
    path('delete/', views.b_delete, name='b_delete'),
    # http://localhost::8000/bbs/like/#post_id
    path('like/', views.b_like, name='b_like'),
    # http://localhost::8000/bbs/createComment/#post_id
    path('createComment/', views.create_comment, name='create_comment'),
    # http://localhost::8000/bbs/commentDelete/
    path('deleteComment/', views.delete_comment, name='delete_comment'),
]

↓views.py↓

from django.shortcuts import render, redirect, get_object_or_404
from bbs.models import Board, Comment
from bbs.forms import BoardForm, BoardDetailForm
from django.http import JsonResponse

def b_list(request):
    posts = Board.objects.all().order_by('-id')
    context = {
        'posts': posts
    }
    return render(request, 'bbs/list.html', context)

def b_create(request):
    # request 방식이 GET or POST인지 구분해서 처리
    # GET 방식이면 빈 입력 상자를 출력하고,
    if request.method == 'GET':

        board_form = BoardForm()
        context = {
           'my_form': board_form
        }
        return render(request, 'bbs/create.html', context)
    # POST 방식이면 client가 입력된 데이터를 이용해서 DB 처리
    else:
        board_form = BoardForm(request.POST) # client가 입력된 데이터를 가지고 있는 ModelForm

        if board_form.is_valid():
            board_form.save()
            # 입력 받은 값 이외에 다른 컬럼의 값을 지정해서 사용할 때(좋아요 개수 10)
            # new_post = board_form.save(commit=False)
            # new_post.b_like_count = 10
            # new_post.save()
            return redirect('bbs:b_list')

def b_detail(request, board_id):
    post = get_object_or_404(Board, pk=board_id)
    board_detail_form = BoardDetailForm(instance=post) # post를 가지고 Model Form 객체를 만듦
    comments = post.comment_set.all().order_by('-id') # 모든 댓글을 발행 역순으로 나열하라
    context = {
        'detail_form': board_detail_form,
        'comments': comments
    }
    return render(request, 'bbs/detail.html', context)

def b_delete(request):
    post_id = request.GET['post_id']
    post = get_object_or_404(Board, pk=post_id)
    post.delete()
    return redirect('bbs:b_list')

def b_like(request):
    post_id = request.GET['post_id']
    post = get_object_or_404(Board, pk=post_id)
    post.b_like_count += 1
    post.save()

    board_detail_form = BoardDetailForm(instance=post)
    context = {
        'detail_form': board_detail_form
    }
    return render(request, 'bbs/detail.html', context)

def create_comment(request):
    comment = Comment()
    comment.c_author = request.GET['comment_author']
    comment.c_content = request.GET['comment_content']
    comment.board_id = request.GET['board_id']
    comment.save()
    # AJAX로 호출되었기 때문에 그 결과가 HttpResponse객체가 아닌 JsonResponse가 나가야 해요!
    # JsonResponse(결과JSON,json_dumps_params={'ensure_ascii': True})
    return JsonResponse({
        'c_id': comment.id,
        'c_author': comment.c_author,
        'c_content': comment.c_content
    },
                        json_dumps_params={'ensure_ascii': True})

def delete_comment(request):
    comment = get_object_or_404(Comment, pk=request.GET['comment_id'])
    comment.delete()
    return JsonResponse({}, json_dumps_params={'ensure_ascii': True})

 

1. 1/17 월 2. 1/18 화 3. 1/19 수 4. 1/20 목 5. 1/21 금
취업 특강 파이썬
환경 설정

(파이참, 아나콘다, 주피터 노트북)
파이썬
데이터 타입

(list, tuple)
파이썬
데이터 타입

(range, string, dictionary, set, bool)
파이썬
사용자 정의 함수,

객체지향,
사용자 정의 클래스
6. 1/24 월 7. 1/25 화 8. 1/26 수 9. 1/27 목 10. 1/28 금
파이썬
사용자 정의 클래스,

사용자 정의 모듈
DB(MySQL)
DBMS,

MySQL 환경 설정,
DB/테이블 생성,
DB 입력·활용,
Index
DB(MySQL)
View,

백업과 복원,
DB 모델링,
관계(PK, FK),
DML(CRUD),
데이터 타입

DB(MySQL)
DML(CRUD),

WHERE 조건,
패턴 매칭,
SubQuery,
정렬,
그룹핑,
집계 함수,
트랜잭션(ACID 특성)
DB(MySQL)
JOIN,

UNION,
NOT IN,
WEB
11. 2/3 목 12. 2/4 금 13. 2/7 월 14. 2/8 화 15. 2/9 수
WEB
WebStorm 환경 설정,

HTML,
CSS,
JavaScript,
jQuery CDN
WEB
jQuery 문법,

Selector,
Method
WEB
jQuery Method,

Event,
AJAX
GitHub 특강
소스코드 관리,

Fork, Clone, Branch,
Commit,
Push, Pull-Request,
Rebase
GitHub 특강
프로젝트 관리,

Fetch, Rebase,
Merge,
Conflict
16. 2/10 목 17. 2/11 금 18. 2/14 월 19. 2/15 화 20. 2/16 수
WEB
jQuery AJAX,

Bootstrap,
Open API
Django
WSGI,

MVC, MVT,
ORM,
투표 시스템
Django
MVT,
ORM
Django
MVT,
ORM,
Redirect
Django
게시판
21. 2/17 목 22. 2/18 금 23. 2/21 월 24. 2/22 화 25. 2/23 수
Django
게시판,
Model Form
Django
게시판,
프로젝트 조 편성
Django
사용자 및 권한 관리,
테스트
   

* 개념, 구조!

728x90

'멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차 > WEB' 카테고리의 다른 글

2/21 월  (0) 2022.02.21
2/17 목  (0) 2022.02.17
2/16 수  (0) 2022.02.16
2/15 화  (0) 2022.02.15
2/14 월  (0) 2022.02.14