[Team_ForV] Django API Server

Update:     Updated:

카테고리:

태그:

Django API Server의 역할

image
Django API Server의 경우 총 3가지의 역할을 하고 있다.

  1. 서버가 올라갈 시 google-cloud-storage로부터 필요한 ai모델파일들을 서버로 불러온다.
  2. 사용자 정보 페이지 요청 시 db를 조회하여 필요한 정보(멤버들의 TMI 정보, 사진 정보 등등)들을 클라이언트에 제공해준다.
  3. 클라이언트로부터 오는 text 요청(특정 목소리로 읽어주었으면 하는 문장)을 db에 저장해둔다.

이처럼, django 서버는 mysql db와 연관된 작업을 많이 수행하도록 구성하였는데, 이는 django의 뛰어난 자체 ORM 때문이라고 볼 수 있다.

ORM이란?

ORM은 Object-Relation Mapping의 준말로, 객체(Object)와 관계형 데이터베이스(Relational)을 연결(Mapping)해주는 것을 말한다.
이를 통해 개발자는 데이터베이스의 테이블에 CRUD(Create, Read, Update, Delete)를 할 때, SQL 쿼리를 사용하지 않고도, 가능하게 된다.
django는 이 ORM을 내장하고 있어, 데이터베이스에 간편하게 접근할 수 있다.

image
위의 테이블들은 이 프로젝트에 쓰인 테이블이다.(로그인 기능을 안 넣었더니 확실히 초라하다..ㅎㅎ)

그렇다면, 이 프로젝트에서 어떤식으로 사용했는지 알아보자.

Model, Serializer, View

image
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)

자, 이렇게 DRFORM을 통해 db 테이블의 구성과 api 세팅을 마쳤다면 django와 mysql과 연동하여 실제로 사용이 가능하도록 만들면 된다.

django와 mysql 연동하기

django는 기본적으로 sqlite3를 사용한다. 하지만 이 프로젝트에서는 mysql를 사용할 것이므로, djangomysql을 연동해주어야 한다. 방법은 간단하다!

  1. mysqlclientpymysql같은 라이브러리를 pip을 통해 설치하고
  2. 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',     # 포트 번호
      } 
    }
    
  3. 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 연결하기]

Team_ForV 카테고리 내 다른 글 보러가기

댓글 남기기