티스토리 뷰
Django에서 Model과 Migrate는 웹 사이트를 개발하는데 있어서 굉장히 자주 사용되며 이와 동시에 Serializers는 정말 수도 없이 작성하게된다. 뭐 사실 저 세가지를 다 깨달아도 view.py 의 GenericView 앞에서는 모두들 무릎꿇겠지만...
어쨌은 오늘 할 이야기는 GenericView는 아니니까 가볍게 Model과 Migrate, 그리고 Serializers의 간단한 예제를 접해보도록 하자.
(GenericView는 마지막에 잠깐(?) 이야기 할거다. 나중에 아주 자세하게 다뤄야하는 챕터가 등장한다. 거기서 자세히 알아보자)
일단 처음으로 할 일은 DB의 테이블을 만들건데 어떤 테이블을 만들거냐 하면 간단하게 게시판의 타입을 저장하는 테이블을 만들어보도록 하겠다.
테이블의 이름은 "board_type" 이라고 하는 것이 좋겠다.
안에 들어갈 컬럼은 아래의 이미지와 같다.
사실 description이고 created_at이고 updated_at도 마찬가지로 쓸데없는 컬럼들인데 블로그에 글쓰려고 일부러 만들었다. 나중에 일일이 설명하기 귀찮아서 그렇다. 한번 만들때 이것저것 다 만들어야 나중에 글 쓸때 편하다. 그러니 양해바란다.
위와 같이 테이블을 만든다고 결정하고 막상 만드려고 할 때 중요한 점은 바로 DB에 작성하는게 아니라는 점이다. models.py에 위의 내용을 작성해 넣는다.
나는 저번에 만든 myhome 프로젝트에 board_type 앱을 새로 만들었다. 그리고 그 안에 models.py 파일을 열어 아래와 같이 작성했다.
(App 만들기를 모르는 경우 이전 글을 참고 할 것. 여기를 클릭해라)
from django.db import models
# Create your models here.
class BoardType(models.Model):
id = models.BigAutoField(primary_key=True)
type = models.CharField(max_length=25, null=False)
description = models.CharField(max_length=100, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'board_type'
이렇게 작성하고 migrate 작업을 실행하자.(작업실행에 대해 모르겠다면 여기를 클릭할 것)
일단 모델을 만들었을 땐 Makemigrations 를 실행해 Migrate 할 수 있도록 준비를 해야한다.
어떤 환경에서 실행할 거냐고 묻는 항목에서는 소문자 엘(L)을 입력한다. 누가 저거 숫자 1로 잘못봤다고 이거 왜 이러냐고 질문하는 사람이 있어서 미리 이야기 한다. 저거 소문자 엘(L)이다.
암튼 위와 같이 MakeMigrations 를 실행하면 BoardType 테이블을 위한 migration 파일이 자동으로 생성된다.
저 파일을 잠깐 열어서 읽어보면 아래와 같은 내용이다.
생성된 앱 폴더 아래에 migrations라는 폴더 아래에 자동생성된 migration 파일을 확인할 수 있다.
이런 모양으로 되어있는데 잘 보면 방금 우리가 작성한 모델과 별반 다를게 없어보인다.
아 참, 여기서 많은 사람들이 질문들을 하시는데 created_at에 있는 "auto_now_add"와 updated_at에 있는 "auto_now" 속성의 차이에 대해서 궁금한 사람들이 많은 것 같다.
간단하게 설명하자면 auto_now_add와 auto_now 둘다 데이터가 생성 혹은 수정되는 시점을 자동으로 채워서 DB에 전달해준다. 다만 auto_now_add는 created_at에서 사용되는 단발성 속성이고 updated_at 은 데이터의 변경이 발생할 때마다 현재 시간을 자동으로 업데이트해주는 차이가 있다.
이렇게 확인을 마쳤으면(굳이 확인할 필요는 없었지만) migrate 명령을 수행해보자.
간편하다. migrate 명령을 수행하면 settings에 포함되어 있는 DB의 정보를 확인하고 Django는 DB에 접근해 자동으로 Table을 생성시켜준다.
그렇다면 DB를 확인해보자.
이렇게 정상적으로 테이블이 생성된 것을 확인할 수 있다.
이런식으로 테이블을 자동으로 생성하게 되면 얻을 수 있는 장점은 Table의 생성, 변경, 반영과 같은 히스토리를 확인 할 수 있게 된다는 점인데 이게 양날의 검이라 히스토리 관리를 잘못한다거나 DB의 값을 임의로 수정하게되면 저장되어있는 히스토리와 내용이 달라서 충돌을 일으킬 수 있다는 단점이 있다.
자, 모델도 DB의 테이블도 정상적으로 생성했다면 이제 Serializers를 작성해볼 필요가 있다. Restframework 때문인지 Python이 원래 그런지는 모르겠는데 태생적으로 DB 모델 객체를 직접 Response하게 되면 오류가 발생한다. 그래서 Serialize 라는 과정이 필요한데 그 과정을 위해서 serializers.py 파일을 만들어서 이용하게 된다.
board_type 폴더에 serializers.py 파일을 만들어보자.
from rest_framework import serializers
from .models import BoardType
class BoardTypeSerializer(serializers.ModelSerializer):
class Meta:
model = BoardType
fields = [
'id'
,'type'
,'description'
,'created_at'
,'updated_at'
]
이렇게 serializers.py 파일을 작성했다면 일단 준비는 마쳤다. 이제 views.py 파일을 열어 API들을 처리할 메서드들을 만들어보자.
이번엔 GenericView 클래스를 이용해 만들거다.
from django.shortcuts import render
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from .serializers import BoardTypeSerializer
from .models import BoardType
# Create your views here.
class BoardListCreateView(ListCreateAPIView):
name = "board-list-create"
serializer_class = BoardTypeSerializer
queryset = BoardType.objects.all()
class BoardRetrieveUpdateDestroyAPIView(RetrieveUpdateDestroyAPIView):
name = "board-retrieve-update-destroy"
serializer_class = BoardTypeSerializer
queryset = BoardType.objects.all()
이렇게 두개의 뷰 클래스를 만들어준다. 하나는 목록과 생성을 담당하는 ListCreateView를 상속받았고 다른 하나는 개별 항목과 수정, 삭제를 담당하는 RetrieveUpdateDestroyView를 상속받았다.
이러면 CRUD의 기본적인 액션과 더불어 목록도 표시할 수 있게 전부 API가 만들어진거다. 그리고 ListCreateView는 Request Method로 POST, GET을 받을 수 있도록 되어있고 RetrieveUpdateDestroy는 GET, PUT, PATCH, DELETE를 받을 수 있도록 되어있다.
이제 urls.py 파일을 만들어서 API 메서드와 URL을 연결시켜주자.
from django.conf.urls import url
from .views import BoardListCreateView, BoardRetrieveUpdateDestroyAPIView
urlpatterns = [
url(r'^board-type/$', BoardListCreateView.as_view(), name=BoardListCreateView.name)
, url(r'^board-type/(?P<pk>[0-9]+)/$', BoardRetrieveUpdateDestroyAPIView.as_view(), name=BoardRetrieveUpdateDestroyAPIView.name)
]
이렇게 urls.py 파일을 작성했으면 이제 프로젝트와 연결하도록 하자.
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
urlpatterns = [
path('admin/', admin.site.urls),
url(r'', include('hello.urls')),
url(r'', include('board_type.urls')),
]
이렇게 연결하고 서버를 기동하면 뭐 달라진걸 확인 할 수는 없을테지만 브라우저에 localhost:8000/board-type 로 접속해보자.
이런 놀라운 화면을 확인 할 수 있을 거다. 아직 DB에 저장된 내용이 없으니 아무것도 나오지 않겠지만 type과 description에 아무거나 입력해보자. 그리고 POST 버튼 클릭.
이렇게 입력한 내용의 결과를 상단에 보여준다. 이제 다시 localhost:8000/board-type에 다시 접속해보자.
이렇게 DB에 저장된 내용을 목록으로 보여준다. 그럼 이제 localhost:8000/board-type/2 로 접속해 보았다. 나는 2개의 레코드를 저장해서 id가 2인 항목을 보기위해 "2"를 입력한거다. 혹시 본인이 1개의 레코드만 저장했다면 2 말고 1이나 암튼 저 위의 이미지 화면에서 보여지는 id 값 아무거나 하나 짚어서 입력한다. 진짜 가끔 데이터 저장도 안하고는 왜 저는 안보일까요 질문하는 사람들이 있어서 미리 설명을 적은거다.
이렇게 적어 놓으면 막 "사람들 무시하나요? 이런거 모르는 사람도 있어요?" 하는 프로불편러들 있는데 내가 학원에서 강사생활 몇년해보니까 진짜 그런 사람 있다. 이건 사람을 무시하는게 아니라 경험에서 나온 이야기다.
암튼 이렇게 접속을 하면 2번 항복에 대한 내용을 확인 할 수 있다. 아래쪽 폼에 내용을 수정해서 입력해보면 내용이 수정되는 것을 확인 할 수도 있다.
그리고 여기서 잘 볼 것은 updated_at의 시간이 바뀌었다는 점이다. 수정을 하면 알아서 현재시간으로 맞춰서 업데이트 된다.
그럼 삭제를 해볼까.
상단의 빨간 DELETE 버튼을 클릭해보자.
여기서 Delete 버튼을 클릭하면
갑자기 내용들이 사라진 것을 볼 수 있고 localhost:8000/board-type으로 가보면 아래의 이미지처럼 2번 레코드가 삭제되어있는 것을 확인 할 수 있다.
엄청 간단하게 CRUD API 5가지(List 보여주는 것 까지 포함해서)를 만들어보았다.
다음시간에는 CROS 셋팅과 AngularJS를 통해 API를 호출하는 법, 그리고 필터링하는 법들에 대해서 알아보도록 하자.
오늘은 여기까지 하자.
'Dev > Python' 카테고리의 다른 글
Django API 연동하기 - 1. 준비운동 (0) | 2018.06.01 |
---|---|
Django CORS 설정과 API 연동 (0) | 2018.05.31 |
Django restframework 시작하기 - Hello,World (0) | 2018.05.29 |
Django를 위하여 -- 환경셋팅 마지막 이야기 (0) | 2018.05.24 |
Django 시작하기 #2. 환경설정 두번째 이야기 (0) | 2018.03.09 |
- TAG
- API서버, Django, GenericView, python, Python Django, restframework, 장고