[Team_ForV] Django API Server
카테고리: Team_ForV
Django API Server의 역할
Django API Server
의 경우 총 3가지의 역할을 하고 있다.
- 서버가 올라갈 시
google-cloud-storage
로부터 필요한 ai모델파일들을 서버로 불러온다. - 사용자 정보 페이지 요청 시 db를 조회하여 필요한 정보(멤버들의 TMI 정보, 사진 정보 등등)들을 클라이언트에 제공해준다.
- 클라이언트로부터 오는 text 요청(특정 목소리로 읽어주었으면 하는 문장)을 db에 저장해둔다.
이처럼, django
서버는 mysql
db와 연관된 작업을 많이 수행하도록 구성하였는데, 이는 django
의 뛰어난 자체 ORM
때문이라고 볼 수 있다.
ORM이란?
ORM
은 Object-Relation Mapping의 준말로, 객체(Object)와 관계형 데이터베이스(Relational)을 연결(Mapping)해주는 것을 말한다.
이를 통해 개발자는 데이터베이스의 테이블에 CRUD
(Create, Read, Update, Delete)를 할 때, SQL 쿼리를 사용하지 않고도, 가능하게 된다.
django
는 이 ORM
을 내장하고 있어, 데이터베이스에 간편하게 접근할 수 있다.
위의 테이블들은 이 프로젝트에 쓰인 테이블이다.(로그인 기능을 안 넣었더니 확실히 초라하다..ㅎㅎ)
그렇다면, 이 프로젝트에서 어떤식으로 사용했는지 알아보자.
Model, Serializer, View
django REST framework(DRF)로 RESTful한 API를 쉽게 만들 수 있다.
1st. 먼저 model.py를 작성한다.
직접 CREATE TABLE 쿼리문을 통해 만드는 것이 아닌, ORM을 통해 class 인스턴스와 db 테이블을 매핑시킨다.
from datetime import datetime
from django.db import models
class Member(models.Model): # 팀원들에 대한 정보
id = models.AutoField(primary_key=True) # primary key
name = models.CharField(max_length=8, null=False) # 이름
birth = models.CharField(max_length=10, null=False) # 생년월일
tmi = models.CharField(max_length=100, default='') # 팀원들의 TMI 정보들
position = models.CharField(max_length=100, default='') # 팀원 각자의 역할
github_link = models.CharField(max_length=100, default='') # 팀원 본인의 깃허브 링크(sns 계정의 일종)
image_link = models.CharField(max_length=100, null=False) # 팀원 본인의 프로필 사진(gcs에 저장해두고 url을 저장)
created_at = models.DateTimeField(default=datetime.now) # 해당 레코드 생성시 현재 시간 자동저장
updated_at = models.DateTimeField(auto_now=True) # 해당 레코드 갱신시 현재 시간 자동저장
class ModelLink(models.Model): # 음성 합성에 필요한 멤버 개개인의 모델 파일 정보(glow-tts, hifi-gan)
id = models.OneToOneField(Member, primary_key=True, on_delete=models.CASCADE, db_column="id")
glow_config = models.CharField(max_length=100, default='', null=False)
glow_pth = models.CharField(max_length=100, default='', null=False)
glow_scale_stats = models.CharField(max_length=100, default='', null=False)
hifi_config = models.CharField(max_length=100, default='', null=False)
hifi_pth = models.CharField(max_length=100, default='', null=False)
hifi_scale_stats = models.CharField(max_length=100, default='', null=False)
created_at = models.DateTimeField(default=datetime.now) # 해당 레코드 생성시 현재 시간 자동저장
updated_at = models.DateTimeField(auto_now=True) # 해당 레코드 갱신시 현재 시간 자동저장
class Text(models.Model): # 사용자들의 문장요구를 db에 저장해두어 추후에 활용하기 위함
member_id = models.ForeignKey(Member, on_delete=models.CASCADE, db_column="member_id")
uuid = models.CharField(max_length=100, default='') # 로그인 대신 uuid를 사용
text = models.CharField(max_length=100, default='') # 사용자가 요청한 문장
created_at = models.CharField(max_length=100, default='') # 레코드 갱신 시점이 아닌 uuid 생성 시점을 기준으로 삼기 때문에 react에서 값을 가져와 저장함
updated_at = models.DateTimeField(auto_now=True) # 해당 레코드 갱신시 현재 시간 자동저장
2nd. serializer.py를 작성한다.
Serializer는 DRF가 제공하는 클래스인데, DB 인스턴스를 JSON 데이터로 생성한다.
이렇게 JSON 포맷으로 직렬화된 문자열은 views에서 클라이언트로 넘겨주게 된다.
from rest_framework import serializers
from .models import Member, ModelLink, Text
class MemberSerializer(serializers.ModelSerializer):
class Meta:
model = Member
fields = '__all__'
class ModelSerializer(serializers.ModelSerializer):
class Meta:
model = ModelLink
fields = '__all__'
class TextSerializer(serializers.ModelSerializer):
class Meta:
model = Text
fields = '__all__'
3rd. views.py를 작성한다.
django에서는 view를 통해서 HTTP 요청을 처리한다.
FBV(함수기반뷰), CBV(클래스기반뷰)를 통해서도 API를 만들 수 있지만,
DRF는 apiview
, mixins
, viewset
등을 제공한다.
각 request method마다 직접 serializer 처리를 해주어야 한다거나,
공통된 queryset과 serializer_class가 반복되는 등의 문제를 해결하기 위해
viewset
을 사용하여 구현했다.
from .serializers import MemberSerializer, ModelSerializer, TextSerializer
from .models import Member, ModelLink, Text
from rest_framework import viewsets
# ViewSet : Post, Get, Put, Delete 기본기능 내장
class MemberViewSet(viewsets.ModelViewSet):
queryset = Member.objects.all()
serializer_class = MemberSerializer
class ModelLinkViewSet(viewsets.ModelViewSet):
queryset = ModelLink.objects.all()
serializer_class = ModelSerializer
class TextViewSet(viewsets.ModelViewSet):
queryset = Text.objects.all()
serializer_class = TextSerializer
4th. url.py를 작성한다.
이렇게 작성한 viewset
을 가지고 url 링크에 매핑해주면, 클라이언트에서 다양한 요청이 들어올 시 처리할 수 있다.
from django.urls import include, path
from .views import *
from rest_framework import routers
from rest_framework import permissions
router = routers.DefaultRouter()
router.register(r'api/members', MemberViewSet)
router.register(r'api/modellinks', ModelLinkViewSet)
router.register(r'api/texts', TextViewSet)
자, 이렇게 DRF
와 ORM
을 통해 db 테이블의 구성과 api 세팅을 마쳤다면 django와 mysql과 연동하여 실제로 사용이 가능하도록 만들면 된다.
django와 mysql 연동하기
django는 기본적으로 sqlite3
를 사용한다. 하지만 이 프로젝트에서는 mysql
를 사용할 것이므로, django
와 mysql
을 연동해주어야 한다. 방법은 간단하다!
mysqlclient
나pymysql
같은 라이브러리를 pip을 통해 설치하고- my_settings.py에 다음과 같은 설정을 작성해주고,
MY_DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 사용할 엔진 설정 'NAME': 'tts', # 연동할 mysql의 데이터베이스 이름 'USER': 'root', # db 접속 계정명 'PASSWORD': '1234', # 해당 db 접속 계정 비밀번호 'HOST': 'ttsmysql', # 실제 db 주소 'PORT': '3306', # 포트 번호 } }
- settings.py에 해당 설정을 import하여 적용시키면 된다.
from .my_settings import MY_DATABASES DATABASES = MY_DATABASES
다음 글 소개
지금까지 django
api server에 대하여 정리해보았다.
다음 포스팅에서는 flask
로 만든 model 서버에 대해 정리해보도록 하자.
Reference
1) https://ssungkang.tistory.com/entry/Django-django-rest-framework-%EB%A5%BC-%EC%9C%84%ED%95%9C-JSON-%EC%A7%81%EB%A0%AC%ED%99%94?category=320582
[django rest framework 를 위한 JSON 직렬화]
2) https://wikidocs.net/book/4223 [점프 투 장고]
3) https://ssungkang.tistory.com/entry/Django-APIView-Mixins-generics-APIView-ViewSet%EC%9D%84-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90
[APIView, Mixins, generics APIView, ViewSet을 알아보자]
4) https://velog.io/@devmin/Django-MySQL-Connect [Django와 MySQL 연결하기]
댓글 남기기