오늘은 http request에 대해 전반적으로 살펴보려고 합니다. 먼저, 새로운 프로젝트를 생성해보겠습니다. 가상환경에 진입한 후, django-admin startproject mypost 를 입력합니다. 다음으로 새로운 앱을 생성하기 위해, mypost 디렉토리에서 python manage.py startapp myblog 를 입력합니다.
이제 myblog에 있는 models.py 코드를 입력할 차례입니다. 아래를 참고하면 단순히 title과 content를 위한 Post class 를 생성한 것을 알 수 있습니다.
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
def __str__(self):
return self.title
이후 mypost에 있는 settings.py 의 INSTALLED_APPS 에 방금 만든 myblog 앱을 추가해줍니다. 이는 myblog에 있는 apps.py 파일의 MyblogConfig class를 가져오겠다는 의미입니다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# My APP
'myblog.apps.MyblogConfig'
]
아래는 views.py 파일의 코드입니다.
from django.shortcuts import render, redirect
# Create your views here.
from .models import Post
def post(request):
#print(request.method) 어떤 형태인지 확인해보기
if request.method == 'POST':
# DB값 추가 / POST 메소드는 딕셔너리 형태
title = request.POST['title']
content = request.POST['content']
Post.objects.create(title=title, content=content)
return redirect('post')
#print(request.POST): 사용자가 보낸 요청들을 딕셔너리 형태로 저장한 것을 확인
#post_list.html에서 {%url 'post' %}가 가리키는 것은 veiws.py의 post 함수
#글을 작성하지 않으면, 즉 request.method == 'GET'이라면 post_list 페이지로 render
posts = Post.objects.all()
return render(
request,
'mypost/post_list.html',
{'posts': posts}
)
mypost 폴더 안에 있는 urls.py 파일을 다음과 같이 수정합니다. include 모듈을 임포트하는 것 잊지마세요!
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('mypost/', include('myblog.urls')) #myblog 내 url 주소를 포함하겠다는 의미
]
이어서 myblog 폴더 안에 있는 urls.py 파일 수정도 필요합니다.
from django.urls import path
from . import views
urlpatterns = [
path('', views.post, name='post')
]
다음은 views.py 에서 렌더링 변환 부분에서 미리 정의한 post_list.html 파일의 코드입니다.
{% for post in posts %}
<br/>
<h2>{{ post.title }} </h2>
<br/>
{{ post.content }}
<br/>
------------
{% endfor %}
<h3> 새로운 글 작성하기 </h3>
<!--form, input, input submit-->
<form action="{% url 'post' %}" method="POST">
{% csrf_token %}
<!--csrf_token을 명시해야 'input type 제출'을 눌렀을 때 오류가 나타나지 않음-->
<!--사용자가 html 화면으로 렌더링할 때 장고가 사용자한테 보내주는 토큰값을 그대로 서버에 보내주는 것으로 사용자 인식이 가능-->
<!--action="": form action에 해당하는 행동을 어디로 보낼 것인지-->
<!--method=POST: body 부분을 채워넣을 때 사용하는 메소드-->
제목 : <input name="title" /><br/>
내용 : <textarea name="content" rows="20">
</textarea>
<input type="submit"/>
</form>
{% csrf_token %} 를 조금 더 설명하자면 장고 웹서버를 실행시키고 views.py 파일의 print(request.POST) 의 주석을 풀어주고 실행해보면 웹서버가 돌아가고 있는 환경에서 QueryDict 에 관한 내용이 나타날 것입니다. 이는 <QueryDict: {'csrfmiddlewaretoken': ['~~'], ~> 와 같은 형태로 구성되어 있습니다.
위에 작성한 views.py 파일의 코드는 단계별로 작성된 것이 아닌 최종 코드를 보여주기 때문에 아래 부가적인 설명을 계속하겠습니다.
post_list.html 에서 설정한 <input type="submit" /> 에 따라 웹 페이지에 생긴 제출 버튼을 눌렀을 때 POST 메소드 요청이 views.py의 post 함수로 들어오게 됩니다. request 메소드가 POST이기 때문에 if문 안의 코드가 실행이 됩니다. 이후 redirect 하면 'post'라는 이름을 가진 경로로 사용자가 보낸 request가 보내지게 되는데, 이 경우에 urls.py 안의 'post'라는 이름을 가진 경로, 즉 다시 views.py의 함수 post로 되돌아오는 것이죠. 다음부터는 if문을 돌지 않고 바로 post = Posts.objects.all() 부터 명령을 실행하는 것입니다. 터미널을 살펴보면 POST -> GET 요청이 연속으로 이루어짐을 알 수 있습니다.
return redirect('post') 가 없다면 웹 페이지 화면에서 새로고침을 할 때마다 똑같은 글이 계속 작성되는 것을 발견할 수 있습니다. 사용자가 처음에 보낸 request가 그대로 사용자에게 되돌아오기 때문입니다. 즉 사용자가 POST 메소드를 통해 보낸 request가 form data에 그대로 남아있는 상황이고 redirect하지 않기 때문에 웹에서는 GET 메소드를 통해 기존에 받았던 request를 데이터베이스에 계속 추가하는 것입니다.
따라서 return redirect() 를 해줘서 사용자가 POST 메소드로 보낸 request 를 없앤 뒤 새로운 요청에 해당하는 내용을 GET 메소드를 이용해 받습니다. 이후 다시 사용자에게 보내주면 저희가 제출한 새로운 title과 comment가 반영되는 것입니다. 아래는 위의 코딩 결과를 보여주는 최종 웹 페이지고, 제목과 내용 부분에 자유롭게 작성하면 실시간으로 반영된답니다.
'문돌이 존버 > Django 스터디' 카테고리의 다른 글
윈도우(window) 버전 Django 세팅 및 코드 예제 (0) | 2020.07.31 |
---|---|
Mac 버전 장고 탬플릿 및 Bootstrap 세팅 (0) | 2020.06.21 |
Mac 버전 장고 데이터베이스 관리 3탄 (1) | 2020.06.20 |
Mac 버전 장고 데이터베이스 관리 2탄 (0) | 2020.06.20 |
Mac 버전 장고 데이터베이스 관리 1탄 (0) | 2020.06.19 |