개발자로서 취업을 하기 위해 포폴을 작성해보고, 여러군데 지원을 해보았으나 번번히 서류탈락을 했다. (흑.. 내가 열씸히 더 노력하고 공부해야겠지?)
개인적으로 프로젝트를 더해볼까 아니면 해왔던 프로젝트를 조금 더 리팩토링을 해볼까 고민을 했는데, 일단 해왔던 프로젝트를 조금 더 RESTful API에 맞게 리팩토링하고, 성능을 최적화 해보아야겠다는 생각이들었다.
그래서 RESTful API를 손쉽게 만들 수 있는 DRF를 공식문서의 Tutorial를 보면서 공부하고자 한다.!
pip install djangorestframework
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, default='')
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']
from rest_framework import serializers
from Snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
class SnippetSerializer(serializers.ModelSerializer):
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
>>> from Snippets.models import Snippet
>>> from Snippets.serializers import SnippetSerializer
>>> a = Snippet.objects.get(id=1)
>>> snippet = SnippetSerializer(a)
>>> snippet.data
{'id': 1, 'title': '', 'code': 'foo = "bar"\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}
ModelSerializer Class
를 이용하여 간편하게 직렬화 시키기ModelSerializer
Class를 상속받고 Snippet
Model를 이용하여 위에서 기본 Serializer를 만든 것보다 간편하게 만들 수 있다.class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ['id', 'title', 'code', 'linenos', 'language', 'style']
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from Snippets.models import Snippet
from Snippets.serializers import SnippetSerializer
@csrf_exempt
def snippet_list(request):
"""
List all code snippets, or create a new snippet.
"""
if request.method == 'GET':
# queryset
snippets = Snippet.objects.all()
# many=True : 다수의 data queryset 형태를 serializer하기 위해 설정 False면 단일 queryset으로 인식
serializer = SnippetSerializer(snippets, many=True)
# safe=False : 직렬화한 개체를 전달하기 위해 설정 True(Default)이면 Dict만 허용
return JsonResponse(serializer.data, safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = SnippetSerializer(data=data)
# 유효성 검사
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
@csrf_exempt
def snippet_detail(request, pk):
"""
Retrieve, update or delete a code snippet.
"""
try:
snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
if request.method == 'GET':
serializer = SnippetSerializer(snippet)
return JsonResponse(serializer.data)
elif request.method == 'PUT':
data = JSONParser().parse(request)
serializer = SnippetSerializer(snippet, data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status=400)
elif request.method == 'DELETE':
snippet.delete()
return HttpResponse(status=204)
>>> http http://127.0.0.1:8000/snippets/
HTTP/1.1 200 OK
Content-Length: 478
Content-Type: application/json
Date: Wed, 30 Jun 2021 02:59:36 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.10
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
[
{
"code": "foo = \"bar\"\n",
"id": 1,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
},
{
"code": "print(\"hello, world\")\n",
"id": 2,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
},
{
"code": "print(\"hello, world\")",
"id": 3,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
},
{
"code": "print(\"New Code Snippet\")",
"id": 4,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
}
]
>>> http http://127.0.0.1:8000/snippets/4/
HTTP/1.1 200 OK
Content-Length: 122
Content-Type: application/json
Date: Wed, 30 Jun 2021 03:02:37 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.10
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"code": "print(\"New Code Snippet\")",
"id": 4,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
}