[작성중] Django 기본 연습

devseunggwan·2020년 9월 8일
0

개요

웹서버를 개발해야할 상황이 생겼다. 이때까지 Flask를 사용하여 REST API 개발을 했지만, 이번 기회에 Django를 사용하여 REST API 를 제작하려 한다.

Django REST framework Docs 1장(Link)을 한글로 적으면서 Django 및 Django REST framework에 대한 내용을 이해하기 위해 문서로 작성한다.

환경 설정

다른 프로그램과 충돌을 방지하기 위해 파이썬 가상환경(venv)를 사용하여 Django를 사용할 환경을 설정한다.

python3 -m venv env
source env/bin/activate

pyenv 가 설치된 경우는 다음과 같이 가상환경을 설정한다.

pyenv install 3.7.6 # pyenv 3.7.6 설치
pyenv virtualenv 3.7.6 RESTenv # pyenv를 사용하여 3.7.6 환경의 가상환경 "RESTenv" 생성
pyenv activate RESTenv # RESTenv로 가상환경 변경

가상환경을 설정한 경우, 해당 환경에서 사용할 Django 프래임워크를 설치한다.

pip install django
pip install djangorestframework
pip install pygment

Django 프로젝트 생성

환경설정이 완료되었다면, 새로운 Django 프로젝트를 생성할 준비가 되었고, Django-admin을 사용하여 프로젝트를 생성해준다.

django-admin startproject tutorial
cd tutorial

생성된 프로젝트 폴더로 이동했다면, API 개발에 사용될 앱을 manage.py 를 사용하여 생성한다.

python manange.py startapp snippets

snippsetsrest_frameworkINSTALLED_APP 에 추가시키기 위해 tutorial/setting.py 를 수정한다.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Add apps
    'rest_framework',
    'snippets.apps.SnippetsConfig',
]

모델 생성

snippets/models.py 을 사용하여 Django에서 사용할 모델을 생성한다.

from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles


LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted([(item, item) for item in get_all_styles()])

class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, defalult='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
    style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
    
    class Meta:
        ordering = ['created']

앱에 생성된 모델에 대한 초기 마이그래이션 후 데이터베이스 동기화를 진행한다.

python manage.py makemigrations snippets
python manage.py migrate

Serializer 클래스 생성

웹 API 상에서 Json 포맷으로 직렬화(Serializing) 나 역직렬화(Deserializing)를 할 수 있는 클래스를 snippets 폴더 내에 serializers.py 을 생성하고 코드를 작성한다.

from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES


class SnippetSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=False, allow_blank=True, max_length=100)
    code = serializers.CharField(style={'base_template': 'textarea.html'})
    linenos = serializers.BooleanField(required=False)
    language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
    style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')

    def create(self, validated_data):
        """
        Create and return a new `Snippet` instance, given the validated data.
        """
        return Snippet.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing `Snippet` instance, given the validated data.
        """
        instance.title = validated_data.get('title', instance.title)
        instance.code = validated_data.get('code', instance.code)
        instance.linenos = validated_data.get('linenos', instance.linenos)
        instance.language = validated_data.get('language', instance.language)
        instance.style = validated_data.get('style', instance.style)
        instance.save()
        return instance

Serializer에 대한 Property Member를 먼저 작성한다. 이후, serializers.Serializer 에서 상속받은 createupdate 를 사용해 생성 및 수정 시 클래스가 취할 행동을 정의한다.

Serializer 클래스 사용

Django Shell 을 사용하여 Serializer 을 사용해본다.

python maange.py shell

Serializer 및 사용할 라이브러리를 import 하고, 클래스 객체를 선언한다.

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

snippet = Snippet(code='foo = "bar"\n')
snippet.save()

snippet = Snippet(code='print("hello, world")\n')
snippet.save()

직렬화

Serializer 을 사용해서 직렬화를 진행한다.

serializer = SnippetSerializer(snippet)
>> serializer.data
# {'id': 2, 'title': '', 'code': 'print("hello, world")\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}

직렬화를 진행한 데이터를 바이너리화 하여 전송할 수 있는 데이터로 변환한다.

content = JSONRenderer().render(serializer.data)
>> content
# b'{"id": 2, "title": "", "code": "print(\\"hello, world\\")\\n", "linenos": false, "language": "python", "style": "friendly"}'

역직렬화

반대로 데이터를 받았을 때 역직렬화도 가능하다. 바이너리 파일을 받은 후에 JSONParser().parse(binary) 를 사용하여 JSON 객체를 반환받을 수 있다. JS에서 많이 본 방법이다.

import io

stream = io.BytesIO(content)
data = JSONParser().parse(stream)

serializer = SnippetSerializer(data=data)

>> serializer.is_valid()
True
>> serializer.validated_data
# OrderedDict([('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
>> serializer.save()
# <Snippet: Snippet object>

작성 중....

profile
변화를 두려워하지 않는 개발자입니다.

0개의 댓글