백엔드 : 서버공부/Django

장고 수정 기능 구현

문코더 2023. 7. 31. 00:28
728x90

이번에는 CRUDUPDATE에대한 기능을 구현해보겠습니다.

CRUD중 가장 어렵다고 알려진 UPDATE는 앞에서 배웠던 모든 기술을 총동원해야 한다고합니다.

구성하려는 페이지 구성은 다음과 같습니다.

페이지의 홈 화면에서는 create 버튼만 나타납니다.

상세보기 페이지를 누르게되면 update버튼이 나타납니다.

그 버튼을 클릭하면 사용자가 선택한 내용이 폼에 들어가있습니다.

글을 수정한 후 제출버튼을 누르면 변경사항이 서버에 전송되고, 변경된 topic의 상세보기 페이지로 이동하게됩니다.

상세보기 페이지에 들어가면 update 링크가 뜨게먼저 함수를 수정해보겠습니다.

아래와같이 HTMLTemplate을 수정해줍니다.

def HTMLTemplate(articleTag, id=None):
    global topics
    contextUI = ''
    if id != None:
        contextUI = f'''
            <li>
                <form action="/myapp/delete/" method="post">
                    <input type="hidden" name="id" value={id}>
                    <input type="submit" value="delete">
                </form>
            </li>
            <li>
                <a href="/myapp/update/{id}">update</a>
            </li>
        '''
    ol = ''
    for topic in topics:
        ol += f'<li><a href="read/{topic["id"]}">{topic["title"]}</a></li>'
    return f'''
    <html>
    <body>
        <h1><a href="/myapp">Django</a></h1>
        <ul>
            {ol}
        </ul>
        {articleTag}
        <ul>
            <li><a href="/myapp/create/">create</a></li>
            {contextUI}
        </ul>
    </body>
    </html>
   '''

아래와 같이 링크를 추가해 update링크로 접속할때 {id}값을 물고 들어가도록 구현하였습니다.

<a href="/myapp/update/{id}">update</a>

이제 저url을 받을수있도록 라우팅 설정을 해보겠습니다.

urls.py에 코드를 추가해보겠습니다.

from django.urls import path
from myapp import views
urlpatterns = [
    path('', views.index),
    path('create/', views.create),
    path('read/<id>/', views.read),
    path('update/<id>',views.update),
    path('delete/',views.delete)
]

위와같이 path를 추가해 코드를 수정합니다.

 

이제 업데이트 함수를 구현해보겠습니다.

사용자가 GET으로 접속하면 UPDATE라는 텍스트를 출력해주고,

POST로 접근하면 상세보기 페이지로 이동하는 것부터 작성해보겠습니다.

아래와 같이 코드를 작성해줍니다.

@csrf_exempt
def update(request, id):
    if request.method == 'GET':
        article = 'Update'
        return HttpResponse(HTMLTemplate(article, id))
    elif request.method == 'POST':
           return redirect(f'/myapp/read/{id}')

페이지를 로드해보면 Update텍스트가 정상적으로 출력되는것을 확인할 수 있습니다.

이제 Update UI를 만들어보겠습니다.

UpdateCreate는 모두 글을 작성하는 폼이필요하므로 코드가 유사합니다.

하지만 Update는 기본적으로 UI안에 데이터가 들어가 있어야한다는 큰 차이점이 있습니다.

때문에 topics를 조회할 필요가있습니다.

그리고 조회에 성공했을때, 그 값을 selectedTopic = {”title”:topic[’title’]}을 통해 selectedTopic이라는 딕셔너리에 담겠습니다.

아래는 수정사항을 반영한 update함수 코드입니다.

@csrf_exempt
def update(request, id):
    global topics
    if request.method == 'GET':
       for topic in topics :
           if topic['id'] == int(id):
               selectedTopic = {
                   "title":topic['title'],
                   "body":topic['body']
               }
       article = f'''
    		<form action="/myapp/update/{id}" method="post">
                <p><input type="text" name="title" placeholder="title" value={selectedTopic["title"]}></p> 
                <p><textarea name="body" placeholder="body">{selectedTopic['body']}</textarea></p>
                <p><input type="submit"></p>
            </form>
        '''
       return HttpResponse(HTMLTemplate(article, id))
    elif request.method == 'POST':
           return redirect(f'/myapp/read/{id}')

페이지를 리로드 한 뒤 update링크를 누르면 선택한 글에해당하는 토픽이 에 채워진 것을 확인할 수 있습니다.

이제 서버로 전송된데이터로 topics변수의 값을 바꾸겠습니다.

먼저 title과 body를 변수로 뽑아내겠습니다.

그후 topics내의 일치하는 값을 뽑아냅니다.

일치한다면 값을 변경시켜줍니다.

그리고 그 과정이 성공했다면 사용자를 /myapp/read/{id} 으로 보내줍니다.

아래는 수정사항을 반영한 함수의 코드입니다.

@csrf_exempt
def update(request, id):
    global topics
    if request.method == 'GET':
       for topic in topics :
           if topic['id'] == int(id):
               selectedTopic = {
                   "title":topic['title'],
                   "body":topic['body']
               }
       article = f'''
    		<form action="/myapp/update/{id}" method="post">
                <p><input type="text" name="title" placeholder="title" value={selectedTopic["title"]}></p> 
                <p><textarea name="body" placeholder="body">{selectedTopic['body']}</textarea></p>
                <p><input type="submit"></p>
            </form>
        '''
    
       return HttpResponse(HTMLTemplate(article, id))
    elif request.method == 'POST':
           title = request.POST['title']
           body = request.POST['body']
           for topic in topics :
                if topic['id'] == int(id):
                    topic['title']=title
                    topic['body']=body
           return redirect(f'/myapp/read/{id}')

페이지를 로드해보겠습니다.

업데이트 링크를 눌러 내용을 수정한뒤 제출버튼을 누르면

위와같이 글의 제목과 내용이 수정되는것을 알 수 있습니다.

 

이제 CRUD의 꽃인 UPDATE구현을 완료하였습니다!