[강의 공부] 11. POST 통신으로 DB 데이터 저장 및 redirect 실습

단간단간·2024년 4월 18일
0
post-thumbnail

⎷ POST 통신으로 DB 데이터 저장

POST 요청으로 받은 Form Data를 DB에 저장하고, DB에 저장된 모든 text 리스트를 노출한다.

  • accountapp > views.py

    from django.http import HttpResponseRedirect
    from django.shortcuts import render
    from django.urls import reverse
    
    from accountapp.models import HelloWorld
    
    def hello_world(request):
        if request.method == "POST":
            text = request.POST.get("hello_world_input")
    
            # DB 저장
            new_hello_world = HelloWorld()
            new_hello_world.text = text
            new_hello_world.save()
    
        hello_world_list = HelloWorld.objects.all()
        return render(request, 'accountapp/hello_world.html', context={'hello_world_list': hello_world_list})
  • hello_world.html 일부

            {% if hello_world_list %}
                {% for hello_world in hello_world_list%}
                <h4>
                    {{ hello_world.text }}
                </h4>
                {% endfor %}
            {% endif %}


⎷ POST/Redirect/GET 패턴 적용

문제점:

  • 그런데, 새로고침을 하면 바로 직전에 보냈던 POST 요청을 동일하게 보낸다.
  • 즉, 새로고침을 하면 이전에 DB에 저장했던 text정보를 반복해서 똑같이 저장하고 있다.

해결책:

  • POST가 성공적으로 끝났으면, GET요청으로 변경하고 싶다. → Redirect 사용
  • django에는 HttpResponseRedirect가 있다.
    • HttpResponseRedirect는 사용자의 브러우저를 주어진 URL로 redirect하기 위해 사용되는 HTTP 응답 클래스이다. django의 view함수에서 URL로의 redirect를 처리할 때 주로 사용된다.
    • HTTP 302 코드를 반환한다.
    • POST후 redirect하는 패턴 :
      폼을 처리한 후 redirect를 수행하여 브라우저가 페이지를 새로 고침할 때 폼 데이터가 중복으로 전송되는 것을 방지할 수 있다. 이를 POST/Redirect/GET 패턴이라고 한다.
    • 하드코딩된 URL 대신, django의 reverse() 메서드를 사용하여 URL을 동적으로 생성하는 것이 좋다. 이 방법은 URL 패턴이 변경될 때 유연하게 대응할 수 있다.

accountapp > views.py

from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse

from accountapp.models import HelloWorld


def hello_world(request):
    if request.method == "POST":
        text = request.POST.get("hello_world_input")

        # DB 저장
        new_hello_world = HelloWorld()
        new_hello_world.text = text
        new_hello_world.save()

        return HttpResponseRedirect(reverse('accountapp:hello_world'))
    else:
        hello_world_list = HelloWorld.objects.all()
        return render(request, 'accountapp/hello_world.html', context={'hello_world_list': hello_world_list})

(참고) reverse 함수

  • django의 reverse 함수는 URL 패턴의 이름과 선택적인 파라미터를 받아 해당 URL 패턴에 일치하는 URL 문자열을 동적으로 생성하는 데 사용된다.
  • 이를 통해 URL을 하드코딩하지 않고도 특정 URL을 참조할 수 있게 해주며, URL의 구조가 변경될 경우에도 동적으로 대응을 해주기 때문에 코드 수정 없이 자동으로 적용되어 편리하다.

accountapp > urls.py

from django.urls import path

from accountapp.views import hello_world

app_name = "accountapp"

urlpatterns = [
    path('hello_world/', hello_world, name='hello_world')
]

urls.py 에서 app_name="accountapp" 설정해주었고, views.pyhello_world 함수path('hello_world/', hello_world, name='hello_world')와 같이 명칭해주었기 때문에 reverse('accountapp:hello_world')가 해당 URL을 찾을 수 있게 된 것.

reverse 함수 테스트

print(reverse('accountapp:hello_world'))
/account/hello_world/
profile
simple is best

0개의 댓글