이 전 게시글에서 개념에 대해 다뤘다면 이번에는 Django의 Rest Framework을 이용해 CRUD(Create, Retrieve, Update, Delete)를 할 수 있는 RESTful 서비스를 구현해 보겠다.
이 실습은 이 링크를 참조하여 진행하였다.
프로젝트 생성 및 기본설정
1. 가상환경, 프로젝트, 앱 생성
#가상환경 만들기
python -m venv venv
source venv/Scripts/activate
#장고 install
pip install django
#프로젝트 생성
django-admin startproject DRFtutorial .
#app생성
python manage.py startapp tutorial
2. settings.py에 생성한 앱 등록
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'tutorial'
]
3. models.py에서 모델을 정의
from django.db import models
class blog(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
author = models.CharField(max_length=20, blank=True, default='')
content = models.TextField()
class Meta:
ordering = ('created',)
4. admin에 모델 등록
from django.contrib import admin
from tutorial.models import blog
class blogAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'created',)
admin.site.register(blog, blogAdmin)
5. URL 설정 (DRFtutorial/urls.py)
from django.conf.urls import url, include
from django.contrib import admin
from django.urls.conf import path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('tutorial.urls')),
]
6. URL 설정 (tutorial/urls.py)
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from tutorial import views
urlpatterns = [
url(r'^$', views.tutorial_list),
url(r'^(?P<pk>[0-9]+)/$', views.tutorial_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns)
7. migration
설정한 파일들을 실제 적용하기 위해 migration 명령어 실행
python manage.py makemigrations #tutorial 하위 디렉토리에 마이그레이션 파일생성
python manage.py migrate #정의한 blog모델로 데이터베이스 테이블 생성
개발
1. Serializer 작성
Serializer 은 데이터를 직렬화 해준다. 이 직렬화를 통해서 메모리상에 있는 변수와 값의 세트를 JSON 데이터로 변환해서 사용할 수 있게 된다.
앱(tutorial)안에 serializers.py 를 생성하여 아래와 같이 입력해준다.
from rest_framework import serializers
from tutorial.models import blog
class blogSerializer(serializers.ModelSerializer):
# ModelSerializer 를 이용해서 아래와 같이 짧은 코드로 직렬화 필드를 정의할 수 있다
class Meta:
model = blog
fields = ('id','title','author','content')
# 신규 blog instance를 생성해서 리턴해준다
def create(self, validated_data):
return blog.objects.create(**validated_data)
# 생성되어 있는 blog instance 를 저장한 후 리턴해준다
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.author = validated_data.get('author', instance.author)
instance.content = validated_data.get('content', instance.content)
instance.save()
return instance
2. view 작성
작성한 serializer을 이용해서 웹으로 부터 요청을 받을 view 파일을 작성한다.
url에서 ' / ' 뒤에 요청이 GET일경우 목록으로 처리하고, POST로 들어오면 입력으로 처리한다.
그리고 '/' 다음에 숫자 값이 입력되어 있을 경우에 GET일 경우 한개의 데이터, PUT은 수정, DELETE는 삭제 처리를 해준다.
tutorial/views.py 에 다음 코드를 작성해준다.
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from tutorial.models import blog
from tutorial.serializers import blogSerializer
# 요청 url 인 tutorial/ 에 대해서 urls.py 에 정의된 view.tutorial_list 가 호출된다.
@api_view(['GET', 'POST'])
def tutorial_list(request, format=None):
if request.method == 'GET':
tutorial = blog.objects.all()
serializer = blogSerializer(tutorial, many=True) # many 값이 True 이면 다수의 데이터 instance를 직렬화할수 있다
return Response(serializer.data)
elif request.method == 'POST':
serializer = blogSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# 요청 url 인 /번호 에 대해서 urls.py 에 정의된 view.tutorial_detail 이 호출된다
@api_view(['GET', 'PUT', 'DELETE'])
def tutorial_detail(request, pk, format=None):
try:
tutorial = blog.objects.get(pk=pk)
except blog.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = blogSerializer(tutorial)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = blogSerializer(tutorial, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
tutorial.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
개발내용 테스트
1. 서버 실행
프로젝트 디렉터리에서 서버를 실행 해준다.
python manage.py runserver
2. 포스트맨을 통한 데이터 입력 요청
데이터 입력 처리 확인을 위해 포스트맨을 열고 아래 처럼 입력한 후, Send를 누릅니다.
3. 브라우저에서 데이터 요청
브라우저를 통해 목록을 요청하면 아래와 같이 Django restframework 에서 지원하는 json 데이터 페이지가 출력된다. 웹 브라우저를 통해 요청하면 아래와 같이 완성된 형태의 페이지가 보여지게 되고, ajax 나 모바일 앱을 통해 요청을 하면 데이터만 받아서 사용할 수 있게 된다.
포스트맨에서도 메소드를 GET으로 설정한후 url ( http://127.0.0.1:8000/ ) 입력하고 Send하면 아래 Body에 값들이 보여진다.
클래스 기반 view 처리
이번에는 코드를 수정하여 기존 함수 기반의 view처리를 클래스 기반으로 변경해볼 것이다.
클래스 기반으로 변경하는 이유는 REST framework 라이브러리 클래스에 CRUD에 대한 기본 처리가 정의되어 있기 때문에 더 짧은 코드로 CRUD를 완성할 수 있기 때문이다.
1. views 수정
tutorial/views.py를 열어 코드 전체를 수정한다.
# 클래스 기반의 Rest CRUD 처리
from tutorial.models import blog
from tutorial.serializers import blogSerializer
from rest_framework import generics
# generics 에 목록과 생성 API 가 정의되어 있다
class blogList(generics.ListCreateAPIView):
queryset = blog.objects.all()
serializer_class = blogSerializer
# generics 에 상세, 수정, 삭제 API가 정의되어 있다
class blogDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = blog.objects.all()
serializer_class = blogSerializer
2. url 수정
tutorial/urls.py 파일을 수정한다.
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from tutorial import views
urlpatterns = [
# 함수형 처리시 호출되는 함수
# url(r'^$', views.tutorial_list),
# url(r'^(?P<pk>[0-9]+)/$', views.tutorial_detail),
# 클래스를 호출하고 해당클래스의 as_view() 함수를 호출
url(r'^$', views.blogList.as_view()),
url(r'^(?P<pk>[0-9]+)/$', views.blogDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
다시 브라우저에서 테스트를 해보아도 이전과 동일하게 동작하는 것을 확인할 수 있다.
이와 같이 Django의 Rest Framework를 사용할 경우 클래스 기반으로 코드를 작성하게 되면 더 짧은 코드로 빠른 시간안에 완성도 높은 결과물을 만들 수 있다.
참고 링크
https://javafa.gitbooks.io/python-django/content/chapter4.html
'# Study > Django' 카테고리의 다른 글
[Study] Django와 Setting (0) | 2021.11.04 |
---|---|
[Study] 백엔드 스터디 4주차 - Django Rest Framework(이론) (0) | 2021.09.01 |
[Study] 백엔드 스터디 3주차 - 배포 방법 (0) | 2021.08.25 |