[작정하고 장고] 4

jinsik·2023년 1월 14일
0

작정하고 장고 15강 - HTTP 프로토콜 GET, POST : Django로 Pinterest 따라하기!

HTTP 프로토콜의 GET, POST

  • user와 server가 통신할 때 보통 user가 request하고 server가 response 한다.
  • 이 때, server는 무엇을 response할 건지 user가 무엇을 필요로 하는지 알려주기 위해 user가 GET이나 POST 등의 방법으로 request를 한다.
  • GET 방식은 보통 조회를 하기 위해 사용한다.
    • 새로 서버에 데이터를 추가하거나 그런 것이 아니기 때문에 URL에 parameter를 넣어 요청한다.
  • POST 방식은 서버에 데이터를 새로 만들거나 수정하기 위해 사용한다.
    • URL에 포함시키지 않고 내부에 있는 body에 데이터를 추가해서 보낸다.

장고로 DB에 데이터를 저장해보기

  1. POST 데이터를 보낸다.
  2. 서버에서 POST 데이터를 받는다.
  3. DB에 저장한다.
  • 먼저 POST로 데이터를 보내기 위해 hello_world.html을 다음과 같이 수정한다.
{% extends 'base.html' %}

{% block content %}
    <div style="border-radius: 1rem; margin: 2rem; text-align: center;">
        <h1 style="font-family: 'Zen Dots', cursive;">
            Hello World LIST!
        </h1>

        <form action="/account/hello_world" method="POST">
            {% csrf_token %}
            <div>
                <input type="text" name="hello_world_input">
            </div>
            <div>
                <input type="submit" class="btn btn-primary" value="POST">
            </div>

        </form>
        <h1>
            {{ text }}
        </h1>
    </div>
{% endblock %}
  • form 태그에 method를 POST로 지정하여 메시지를 보낼 수 있다.
  • 이 때, text를 hello_world_input에 담아 submit 하면 서버에서 view를 이용해 처리한 후 아래쪽의 text로 뿌려지게 할 것이다.
  • 그러므로 views.py도 다음과 같이 수정한다.
from django.shortcuts import render

# Create your views here.

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

		return render(request, 'accountapp/hello_world.html', context={'text': temp})
	else:
		return render(request, 'accountapp/hello_world.html', context={'text': 'GET Method!!'})
  • 변수 temp에 POST로 받은 hello_world_input의 내용을 넣는다.
  • 그 후 다시 그 페이지를 render하는데 text 부분에 받은 텍스트를 넣어주는 방식이다.
  • 이제 POST로 메시지를 보내고 처리하는 것 까지 해보았으니 DB에 저장을 해보자.
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse
from accountapp.models import HelloWorld

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

		new_hello_world = HelloWorld()
		new_hello_world.text = temp
		new_hello_world.save()

		return render(request, 'accountapp/hello_world.html', context={'hello_world_output': new_hello_world})
	else:
		return render(request, 'accountapp/hello_world.html', context={'text': 'GET Method!!'})
  • temp 아래 세 줄과 return할 때 text가 아닌 HelloWorld 모델의 객체 new_hello_world를 리턴하는 것으로 수정하였다.
  • HelloWorld 모델을 import 시키고 그 인스턴스를 만들었다.
  • HelloWorld 모델에 속성 text에 temp를 넣어주었다.
  • new_hello_world.save()를 하게 되면 DB에 저장된다.
  • render 할 때 context로 모델의 인스턴스를 반환하였으니 hello_world.html도 다음과 같이 처리해주어야 한다.
{% extends 'base.html' %}

{% block content %}
    <div style="border-radius: 1rem; margin: 2rem; text-align: center;">
        <h1 style="font-family: 'Zen Dots', cursive;">
            Hello World LIST!
        </h1>

        <form action="/account/hello_world" method="POST">
            {% csrf_token %}
            <div>
                <input type="text" name="hello_world_input">
            </div>
            <div>
                <input type="submit" class="btn btn-primary" value="POST">
            </div>

        </form>

        {% if hello_world_output %}
        <h1>
            {{ hello_world_output.text }}
        </h1>
        {% endif %}
    </div>
{% endblock %}
  • hello_world_output이 존재한다면 endif까지의 html을 쓰게 된다.
  • 한 번 post를 해보고 DB에 저장되었는지 확인해보자.

DB에 저장된 내용을 display

{% extends 'base.html' %}

{% block content %}
    <div style="border-radius: 1rem; margin: 2rem; text-align: center;">
        <h1 style="font-family: 'Zen Dots', cursive;">
            Hello World LIST!
        </h1>

        <form action="/account/hello_world" method="POST">
            {% csrf_token %}
            <div>
                <input type="text" name="hello_world_input">
            </div>
            <div>
                <input type="submit" class="btn btn-primary" value="POST">
            </div>

        </form>

        {% if hello_world_list %}
            {% for hello_world in hello_world_list %}
            <h4>
                {{ hello_world.text }}
            </h4>
            {% endfor %}
        {% endif %}
    </div>
{% endblock %}
  • hello_world.html을 위와 같이 수정해준다.
  • hello_world_list라는 반복 가능한 자료형에서 개체들의 text를 뽑아서 보여줄 것이다.
  • 그러므로 views.py도 다음과 같이 수정한다.
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse
from accountapp.models import HelloWorld

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

		new_hello_world = HelloWorld()
		new_hello_world.text = temp
		new_hello_world.save()

		hello_world_list = HelloWorld.objects.all()
		return render(request, 'accountapp/hello_world.html', context={'hello_world_list': hello_world_list})
	else:
		hello_world_list = HelloWorld.objects.all()
		return render(request, 'accountapp/hello_world.html', context={'hello_world_list': hello_world_list})
  • POST 방식이든 GET 방식이든 hello_world_list에 DB에 있는 HelloWorld 모델의 모든 오브젝트를 넣어 반환하여 뿌려주게 된다.
  • 정상적으로 작동하는지 한번 테스트 해보자.
  • 하지만 다음에, 새로고침을 하게 되면 이전에 넣었던 양식대로 계속 post되어 똑같은 것이 추가되는 문제가 있다.
    • 이는 render가 아니라 HttpResponseRedirect를 이용해서 해결 가능하다.
    • views.py를 아래와 같이 수정한다.
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse, HttpResponseRedirect
from accountapp.models import HelloWorld
from django.urls import reverse

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

		new_hello_world = HelloWorld()
		new_hello_world.text = temp
		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})
  • 이러면 새로고침을 해도 이전에 post했던 내용을 똑같이 post 하는 것이 아니고 자신의 페이지로 리다이렉트를 하기 때문에 post되지 않는다.
profile
공부

0개의 댓글