저번 글에서 이어서 계속 진행해볼 것이다. 저번 게시글에서 프로젝트와 앱을 생성하고 setting.py에 등록까지 하고 마쳤었다.
여기까지 하고 터미널창에 아래의 Command들을 차례로 입력하면 서버를 실행시킬 수 있다.
python manage.py migrate
위 명령어는 DB에 변경사항을 적용하는 명령어로 방금과 같은 최초 실행 시, 그리고 DB관련 변경사항(model수정)반영 시에 사용한다.
python manage.py runserver
위 명령어는 말 그대로 서버를 작동시키는 명령어이다.
정상적으로 실행이 됐다면 아래와 같은 화면이 뜰 것이다.
이제부터 간단하게 글을 작성하고 저장할 수 있는 사이트를 만들어보면서 Django에 대한 작동 흐름을 살펴볼 것이다.
전에 작성한 포스트를 살펴보면 우선 Client가 특정 url에 접근함으로써 그에 해당하는 views.py에서 특정 동작을 수행한다는 것을 알 수 있다. 따라서 url과 그에 따른 동작을 정의한 view를 mapping시켜주어야 한다.
urls.py 작성#config > urls.py
from django.contrib import admin
from django.urls import path
from posts import views <<추가
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.home), <<추가
]
posts라는 앱의 views.py에서 home이라는 이름으로 정의된 view를 아무것도 없는 url, 즉 127.0.0.1:8000에 대한 접근 시에 호출한다는 것을 의미한다.
views.py 작성#posts > views.py
from django.shortcuts import render
def home(request): <<추가
return render(request, 'index.html', name='home')
위 코드는 urls.py에서 127.0.0.1:8000, 즉 아무것도 이름이 정해지지 않은 url에 접근 시 동작할 view, home이라는 함수를 작성한 내용이다. return문에 있는render는 React를 접해봤다면 알 수 있다시피 index.html이라는 템플릿을 화면에 그려준다는 것을 의미한다.
Client에게 보이는 부분이 이 Template부분이다. Template은 앞에 작성한 urls.py와 views.py와 달리 templates라는 폴더를 앱 안에 만들고 사용해야 한다. 이때 templates라는 폴더는 오타없이 철자 그대로 적어야 Django내에서 인식이 가능하다.
<!-- posts > template > index.html -->
<h1>메인 페이지</h1>
이렇게 작성을 마치고 서버를 실행하면 다음과 같은 창이 뜰 것이다.
model 생성MTV패턴에서 db와 직접 상호작용하는 부분이 바로 이 model부분이었다. 이제 글을 저장할 수 있는 model과 글을 작성할 수 있는 form을 만들 것이다.
models.py 작성#post > models.py
from django.db import models
class Post(models.Model):
title=models.CharField(max_length=20)
description=models.TextField()
def __str__(self):
return self.title
위와 같이 클래스로 model을 만들수 있다. 이 한개의 클래스는 db상에 하나의 table로 생성되며 그 안의 Field에 지정해놓은 형태로 column이 생성된다.
Model의 변경사항을 DB에 반영이렇게까지 한 후 다음 명령어들을 차례로 입력하면 model에 대응되는 table이 생성된다.
python manage.py makemigrations
python manage.py migrate
python manage.py makemigrations:model의 변경사항을 파일로 만들어주는 역할을 한다.
위에
0001_initial.py라는 파일에model의 변경사항이 저장된다. 프로젝트를 진행하다가models.py를 수정한다면 반드시 위 명령어를 실행해주어야 한다.
그 후 python manage.py migrate를 통해 db변경사항을 반영시켜주어야 한다. 그러면 다음과 같이 db상에 table이 생성된다.여기서 우리가 눈여겨봐야 할 부분은
posts_post라는 table이다. 이 table이 models.py안에 작성한 클래스로 인해 생성된 table이다.
위를 보면 우리가 models.py에서 만든 title과 description이라는 column이 생성된 것을 알 수 있다. 여기서 id값은 장고에서 테이블을 만들 때 자동으로 생성해준 primarykey이다.
장고에서는 우리가 models.py에서 생성한 model을 가져와서 사용자가 정보를 입력할 수 있는 form으로 만들 수 있다.
forms.py는 앱 생성시 기본으로 생기는 파일이 아니기 때문에 파일을 별도로 만들어주어야 한다.
#post > forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
title = forms.CharField(
max_length=20,
label='제목',
widget=forms.TextInput(
attrs={
'class': 'my-input',
'placeholder': '제목 입력',
'col' : 50,
}
)
)
description = forms.CharField(
label='내용',
widget=forms.Textarea(
attrs={
'row': 5,
'col': 50,
}
)
)
class Meta:
model=Post
fields='__all__'
forms.py에 대해서는 여기서 다루기엔 양이 너무 많아지기 때문에 자세한 설명은 생략하겠다. 우리는 여기서 Meta부분만 확인해도 된다. 대략적으로 Post라는 model을 가져와 사용한다는 것을 알 수 있다.
1-3번에서와 마찬가지로 Templates 폴더 안에 글 작성 form을 rendering 할 html파일을 생성한다.
자세히 살펴보면 우리가 기존에 알고 있던 html파일과는 다른 것을 알 수 있다.
바로 {% csrf_token %}과 {{form.as_p}}이 추가됐는데 이것이 장고에서 기본적으로 제공되는 템플릿 언어이다.
<!--post > templates > postform-->
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<button type="submit">제출</button>
</form>
위에서 우리가 작성한 home밑에 우리가 Client로부터 form으로 전달받은 데이터를 저장하는 view인 postform을 작성할 것이다. 이 포스트에서는 코드에 대한 설명은 간단하게 주석으로 하겠다.
#post > views.py
from django.shortcuts import redirect, render << 수정
def postform(request):
if request.method=='POST':
#요청 메소드가 POST라면
form=PostForm(request.POST)
#POST요청으로 받은 정보를 PostForm에 넣고 저장
if form.is_valid:
#form의 데이터가 유효하다면
form.save()
#form을 db에 저장
return redirect('home')
#그 후 index.html로 redirect
else:
#POST요청이 아니라면
form=PostForm()
#비어있는 PostForm을
return render(request,'postform.html',{'form': form})
#rendering시 넘겨준다.
이제 우리가 만든 view함수를 새로운 url과 mapping시켜주어야 한다.
#config > urls.py
from django.contrib import admin
from django.urls import path
from posts import views
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.home, name='home'),
path('create/',views.postform, name='create'), <<추가
]
그리고 index.html에서 글 작성폼이 들어있는 postform.html을 접근 할 수 있도록 링크를 생성해주어야 한다.
<!-- posts > template > index.html -->
<h1>메인페이지</h1>
<a href="{% url 'create' %}">글작성</a>
이 후 서버를 작동시키면 "글작성"이라는 링크가 메인페이지에 생겼을 것이다. 그 링크를 타고 들어가 글을 작성한 후에 제출하고 아까 확인했던 db를 확인하면 다음과 같이 데이터가 들어가 있을 것이다.
이를 통해 사용자가 입력한 글이 db에 정상적으로 저장되었음을 확인할 수 있다.
이렇게 간단하게 글 작성 홈페이지를 작성하면서 장고의 대략적인 작동원리에 대해서 알아보았다. 이에 대해서 간단하게 정리해보겠다.
- 서버 실행
- "http://127.0.0.1:8000" 이라는 로컬주소에 진입하면 url mapping을 통해
home이라는views.py있는 함수가 실행된다. 이 함수는index.html을 rendering 해준다.- 화면에서
글 작성이라는 링크를 통해 "http://127.0.0.1:8000/create/" 이라는 url로 접근한다.- "http://127.0.0.1:8000/create/" 에 접근한다면
urls.py에서views.py안의postform이라는 함수를 실행한다.- 만약
postform안에서 정의된 조건에 따라 만약 이 주소에서 사용자가 POST요청을 보낸다면 POST요청을 가공하여db에 저장한다
막상 글로 풀어서 정리하면 어려워 보이지만 이 포스트 전체는 저번 게시글에서 설명한 MTV패턴에 대한 예라고 생각하면 된다.
Django는
MTV패턴을 사용하는웹Framework이다. Django의MTV패턴은 다음과 같은 틀에서 구현된다.
models.py안의class->Model->db와 상호작용views.py안의함수 or Class->View-> 웹사이트 내부의 논리templates안의 여러 html파일 ->template->Client와 상호작용