이 블로그 검색

2012년 8월 7일 화요일

Django 게시판 만들기 3 - 글 조회 및 수정, 삭제 기능 구현


목록에서 글 보기를 위한 url은 /viewWork 로 설정했고, GET방식으로 글 조회를 위한 정보를 전달하게 되어 있었다. 그럼 할일은 앞서와 마찬가지로 url 과 컨트롤러 맵핑이 되겠다. 먼저 컨트롤러 추가.

def viewWork(request):
    pk= request.GET['memo_id']
    boardData = DjangoBoard.objects.get(id=pk)

    
    # 조회수를 늘린다.    
    DjangoBoard.objects.filter(id=pk).update(hits = boardData.hits + 1)

    
    return render_to_response('viewMemo.html', {'memo_id': request.GET['memo_id'],
                                                'current_page':request.GET['current_page'],
                                                'searchStr': request.GET['searchStr'],
                                                'boardData': boardData } )

여기서는 테이블의 PK값인 id를 알고 있으므로, model의 DjangoBoard.objects.get(id=pk) 츨 호출해서 해당 데이터를 얻을수 있다. 그리고 구한 게시물 정보를 템플릿으로 넘겨주고 있다. url을 추가한다.

urlpatterns = patterns('',
    url(r'^$', views.home),
    url(r'^show_write_form/$', views.show_write_form),
    url(r'^DoWriteBoard/$', views.DoWriteBoard),
    url(r'^listSpecificPageWork/$', views.listSpecificPageWork),
    url(r'^viewWork/$', views.viewWork),
)

그 다음은? viewMemo.html 템플릿을 생성한다. 간단한 게시판이라서 그런지 정말 간단하다.^^
  <html>
  <head>
  <title>글보기</title>
  </head>

  <script language="javascript">
      function boardlist()
      {
          var s = "{{searchStr}}";

          if(s=="None")
              location.href = '/listSpecificPageWork?current_page={{current_page}}';
          else
              location.href = '/listSearchedSpecificPageWork?pageForView={{current_page}}&searchStr={{searchStr}}';
      }

      function boardmodify()
      {
          location.href='/listSpecificPageWork_to_update?memo_id={{memo_id}}&current_page={{current_page}}&searchStr={{searchStr}}';
      }

      function boarddelete()
      {
          location.href='/DeleteSpecificRow?memo_id={{memo_id}}&current_page={{current_page}}';
      }
  </script>
  <table cellspacing = 0 cellpadding = 5 border = 1 width=500>
      <tr><td><b>조회수</b></td><td> {{ boardData.hits }} </td></tr>
      <tr><td><b>이름 </b></td><td> {{ boardData.name }} </td></tr>
      <tr><td><b>이메일 </b></td><td> {{ boardData.mail }} </td></tr>
      <tr><td><b>제목 </b></td><td> {{ boardData.subject }} </td></tr>
      <tr><td><b>내용 </b></td><td width=350> {{ boardData.memo }} </td></tr>
  </table>

  <table  cellspacing = 0 cellpadding = 0 border = 0 width=500>
      <tr><td>
          <input type=button value="수정" OnClick="javascript:boardmodify()">
          <input type=button value="목록" OnClick="javascript:boardlist()">
          <input type=button value="삭제" OnClick="javascript:boarddelete()">
      </td></tr>
  </table>
  </html>

여기까지 작업한 결과, 글 목록에서 해당 게시물을 클릭하면 다음처럼 내용이 조회된다.



이제 이 화면에서의 처리를 작업해야 한다. 처리 해야할 기능은 버튼 3가지, 즉, 목록, 수정, 삭제가 되겠다.

목록 기능 구현
먼저 목록을 누른 경우를 생각해보자. javascript 로 처리한 부분을 보면 검색 문자열이 있는 경우와 없는 경우를 구분해서 다른 url을 호출하고 있다. 이는 검색된 상태에서 글을 보고 목록으로 돌아가는 경우( /listSearchedSpecificPageWork )와 그렇지 않은 경우를 처리하기 위함이다. 목록 처리를 위해서 /listSpecificPageWork 는 이미 구현해 놓았으므로 처리할게 없고, /listSearchedSpecificPageWork, 이것에 대한 url과 그 컨트롤러를 추가해줘야 겠다.

컨트롤러에 추가후 url 맵핑을 해준다.

def listSearchedSpecificPageWork(request):
    searchStr = request.GET['searchStr']
    pageForView = request.GET['pageForView']

    # 다음은 테이블에서 subject 항목에 대해 LIKE SQL을 수행한다.
    totalCnt = DjangoBoard.objects.filter(subject__contains=searchStr).count()

    pagingHelperIns = pagingHelper();
    totalPageList = pagingHelperIns.getTotalPageList( totalCnt, rowsPerPage)

    # Raw SQL에 like 구문 적용방법.. 이 방법 찾다가 삽질 좀 했다.
    boardList = DjangoBoard.objects.raw("""SELECT Z.* FROM ( SELECT X.*, ceil(rownum / %s) as page \
        FROM ( SELECT ID,SUBJECT,NAME, CREATED_DATE, MAIL,MEMO,HITS FROM SAMPLE_BOARD_DJANGOBOARD \
        WHERE SUBJECT LIKE '%%'||%s||'%%' ORDER BY ID DESC) X ) Z WHERE page = %s""", [rowsPerPage, searchStr, pageForView])

    return render_to_response('listSearchedSpecificPage.html', {'boardList': boardList, 'totalCnt': totalCnt,
                                                        'pageForView':int(pageForView) ,'searchStr':searchStr, 'totalPageList':totalPageList} )

- url 맵핑 urlpatterns = patterns('',
    url(r'^$', views.home),
    url(r'^show_write_form/$', views.show_write_form),
    url(r'^DoWriteBoard/$', views.DoWriteBoard),
    url(r'^listSpecificPageWork/$', views.listSpecificPageWork),
    url(r'^viewWork/$', views.viewWork),
    url(r'^listSearchedSpecificPageWork/$', views.listSearchedSpecificPageWork),
)

listSearchedSpecificPage.html 템플릿을 추가한다. 원래 검색기능은 처음 게시물 목록 보기 화면 listSpecificPage.html 에 있으므로
먼저 이 기능 구현을 해야 했어야 하는데, 글 조회 화면의 기능을 구현하면서 이 템플릿을 작성하고 있는 것이니 착오없기 바란다.

  listSearchedSpecificPage.html

  <table cellspacing=1 width=700 border=0>
      <tr>
          <td>총 게시물수: {{ totalCnt }}</td>
          <td><p align=right> 페이지:{{ pageForView }}
          </td>
      </tr>
  </table>

  <table cellspacing=1 width=700 border=1>
      <tr>
          <td width=50><p align=center>번호</p></td>
          <td width=100><p align=center>이름</p></td>
          <td width=320><p align=center>제목</p></td>
          <td width=100><p align=center>등록일</p></td>
          <td width=100><p align=center>조회수</p></td>
      </tr>

      {% if boardList %}
          <ul>
              {% for boardRow in boardList %}
              <tr>
              <td width=50><p align=center>{{ boardRow.id }}</p></td>
              <td width=100><p align=center>{{ boardRow.name }}</p></td>
              <td width=320>
                  <p align=center>
                      <a href="/viewWork?memo_id={{ boardRow.id }}&current_page={{ pageForView }}&searchStr={{searchStr}}" title="{{ boardRow.memo}}">{{ boardRow.subject }}
                  </p>
              </td>
              <td width=100><p align=center>{{ boardRow.created_date }}</p></td>
              <td width=100><p align=center>{{ boardRow.hits }}</p></td>
              </tr>
              {% endfor %}
          </ul>
      {% else %}
          <p>No Data.</p>
      {% endif %}
  </table>

  <table cellspacing=1 width=700 border=1 >
      <tr> <td>
          {% for page in totalPageList %}
              <a href="/listSearchedSpecificPageWork?searchStr={{searchStr}}&pageForView={{page}}" >
              [
              {% ifequal page pageForView %}
                  <b>
              {% endifequal %}
              {{page}}

              {% ifequal page pageForView  %}
                  </b>
              {% endifequal %}
              ]
          {% endfor %}
          </td> </tr>
  </table>

  <table width=700>
      <tr>
          <td><input type=button value="전체 목록으로 돌아가기"  OnClick="window.location='/'">
      </tr>
  </table>

먼저 보았던 listSpecificPage.html 과 searchStr 처리부분만 틀리고 거의 동일하다는것을 참고하기 바란다. 지금까지 목록 버튼 처리를 구현했다.

수정 버튼 구현
이제 수정 버튼을 구현할 차례이다. 수정 기능은 먼저 해당 게시물 데이터를 조회해서 폼에 채워주고 재작성시의 처리 url과 컨트롤러를 맵핑 해주면 된다. 우리는 수정을 위한 url을 /listSpecificPageWork_to_update 로 설정 했으므로, 컨트롤러 작성 및 url 맵핑을 절차대로 수행한다.

- 컨트롤러 작성
def listSpecificPageWork_to_update(request):
    memo_id = request.GET['memo_id']
    current_page = request.GET['current_page']
    searchStr = request.GET['searchStr']
    boardData = DjangoBoard.objects.get(id=memo_id)
    return render_to_response('viewForUpdate.html', {'memo_id': request.GET['memo_id'],
                                                'current_page':request.GET['current_page'],
                                                'searchStr': request.GET['searchStr'],
                                                'boardData': boardData } )

- url 맵핑
urlpatterns = patterns('',
    url(r'^$', views.home),
    url(r'^show_write_form/$', views.show_write_form),
    url(r'^DoWriteBoard/$', views.DoWriteBoard),
    url(r'^listSpecificPageWork/$', views.listSpecificPageWork),
    url(r'^viewWork/$', views.viewWork),
    url(r'^listSearchedSpecificPageWork/$', views.listSearchedSpecificPageWork),
    url(r'^listSpecificPageWork_to_update/$', views.listSpecificPageWork_to_update),
)

- 템플릿 작성 : viewForUpdate.html

<html>
<head>
<title>글보기</title>
</head>

<script language="javascript">
function writeCheck()
{
   var form = document.modifyform;

   if( !form.subject.value )
   {
       alert( "제목을 적어주세요" );
       form.subject.focus();
       return;
   }
   if( !form.memo.value )
   {
       alert( "내용을 적어주세요" );
       form.memo.focus();
       return;
   }
   form.submit();
}

function boardlist()
{
   var s = "{{searchStr}}";

        if(s=="None")
            location.href = '/listSpecificPageWork?current_page={{current_page}}';
        else
            location.href = '/listSearchedSpecificPageWork?pageForView={{current_page}}&searchStr={{searchStr}}';
}
</script>

<table cellspacing = 0 cellpadding = 5 border = 1 width=500>
<form name=modifyform method=post action="/updateBoard/">
    <input type=hidden name=memo_id  value="{{memo_id}}">
    <input type=hidden name=current_page  value="{{current_page}} ">
    <input type=hidden name=searchStr  value="{{searchStr}} ">

    <tr><td><b>이름</b></td><td>{{ boardData.name }}<input type=hidden name=name size=50  maxlength=30 value="{{ boardData.name }}"></td><tr>
    <tr><td><b>이메일</b></td><td><input type=text name=mail size=50  maxlength=50 value="{{ boardData.mail }}"></td></tr>
    <tr><td><b>제목</b></td><td><input type=text name=subject size=50  maxlength=50 value="{{ boardData.subject }}"></td></tr>
    <tr><td><b>내용</b></td><td><textarea name=memo cols=50 rows=10>{{ boardData.memo }}</textarea></td></tr>
</form>
</table>

<table  cellspacing = 0 cellpadding = 0 border = 0 width=500>
    <tr><td>
        <input type=button value="재등록" OnClick="javascript:writeCheck();">
        <input type=button value="목록" OnClick="javascript:boardlist()">
    </td></tr>
</table>
</html>

템플릿 파일에서 재등록시 수행되는 url 을 /updateBoard/ 로 설정 했으므로, 컨트롤러 추가및 url 맵핑을 실시한다.

- 컨트롤러 작성
@csrf_exempt
def updateBoard(request):
    memo_id = request.POST['memo_id']
    current_page = request.POST['current_page']
    searchStr = request.POST['searchStr']

    # Update DataBase
    DjangoBoard.objects.filter(id=memo_id).update(
                                                  mail= request.POST['mail'],
                                                  subject= request.POST['subject'],
                                                  memo= request.POST['memo']
                                                  )

    # Display Page => POST 요청은 redirection으로 처리하자
    url = '/listSpecificPageWork?current_page=' + str(current_page)
    return HttpResponseRedirect(url)

- url 맵핑
urlpatterns = patterns('',
    url(r'^$', views.home),
    url(r'^show_write_form/$', views.show_write_form),
    url(r'^DoWriteBoard/$', views.DoWriteBoard),
    url(r'^listSpecificPageWork/$', views.listSpecificPageWork),
    url(r'^viewWork/$', views.viewWork),
    url(r'^listSearchedSpecificPageWork/$', views.listSearchedSpecificPageWork),
    url(r'^listSpecificPageWork_to_update/$', views.listSpecificPageWork_to_update),
    url(r'^updateBoard/$', views.updateBoard),
)

모델을 이용해서 update를 수행했다.

삭제 기능 구현
자..지금까지 목록, 수정 가능을 구현했고 이제 삭제 기능을 구현할 차례이다. 컨트롤러와 url 맵핑을 수행한다. model을 이용해서 delete를 수행한다.

- 컨트롤러 작성
def DeleteSpecificRow(request):
    memo_id = request.GET['memo_id']
    current_page = request.GET['current_page']

    p = DjangoBoard.objects.get(id=memo_id)
    p.delete()
   
    # 마지막 메모를 삭제하는 경우, 페이지를 하나 줄임.
    totalCnt = DjangoBoard.objects.all().count()
    pagingHelperIns = pagingHelper();

    totalPageList = pagingHelperIns.getTotalPageList( totalCnt, rowsPerPage)
    print 'totalPages', totalPageList

    if( int(current_page) in totalPageList):
        print 'current_page No Change'
        current_page=current_page
    else:
        current_page= int(current_page)-1
        print 'current_page--'

    url = '/listSpecificPageWork?current_page=' + str(current_page)
    return HttpResponseRedirect(url)

- url 맵핑
urlpatterns = patterns('',
    url(r'^$', views.home),
    url(r'^show_write_form/$', views.show_write_form),
    url(r'^DoWriteBoard/$', views.DoWriteBoard),
    url(r'^listSpecificPageWork/$', views.listSpecificPageWork),
    url(r'^viewWork/$', views.viewWork),
    url(r'^listSearchedSpecificPageWork/$', views.listSearchedSpecificPageWork),
    url(r'^listSpecificPageWork_to_update/$', views.listSpecificPageWork_to_update),
    url(r'^updateBoard/$', views.updateBoard),
    url(r'^DeleteSpecificRow/$', views.DeleteSpecificRow),
)

글 조회 화면에서 목록보기, 수정, 삭제의 기능을 모두 구현하였다. 다음은 전체 목록 화면에서 검색 기능 구현이다.


이 예제의 전체 소스는 아래에서 받을 수 있다.
https://github.com/jeremyko/dj_board

이어지는 글:

Django 게시판 만들기 4 - 검색 기능 구현

댓글 없음:

댓글 쓰기