Skip to content

Instantly share code, notes, and snippets.

@askcompany-kr
Last active July 17, 2019 18:28
Show Gist options
  • Select an option

  • Save askcompany-kr/a55ec9a794ef23941000cfa66d3d9736 to your computer and use it in GitHub Desktop.

Select an option

Save askcompany-kr/a55ec9a794ef23941000cfa66d3d9736 to your computer and use it in GitHub Desktop.
[Ask Company] django-rest-framework를 활용한 HTTP API 서버 만들기, 예시 코드
#
# myapp/models.py
#
from django.db import models
class Post(models.Model):
message = models.TextField()
#
# myapp/forms.py
#
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
#
# myapp/views.py
#
from django.http import HttpResponse, JsonResponse
from django.http import QueryDict
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from .models import Post
from .forms import PostForm
@csrf_exempt
def post_list(request):
if request.method == 'GET':
qs = Post.objects.all()
data = [{'pk': post.pk, 'message': post.message} for post in qs] # 수동 JSON 직렬화
return JsonResponse(data, safe=False)
elif request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
post = form.save()
return HttpResponse(status=201)
data = form.errors
return JsonResponse(data, status=400)
@csrf_exempt
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == 'GET':
return JsonResponse({'pk': post.pk, 'message': post.message})
elif request.method == 'PUT':
put = QueryDict(request.body)
form = PostForm(put, instance=post)
if form.is_valid():
post = form.save()
data = {'pk': post.pk, 'message': post.message}
return JsonResponse(data=data, status=201)
return JsonResponse(form.errors)
elif request.method == 'DELETE':
post.delete()
return HttpResponse('', status=204)
#
# myapp/urls.py
#
from django.conf.urls import url
from .views import post_list, post_detail
urlpatterns = [
url(r'^post/$', post_list, name='post-list'),
url(r'^post/(?P<pk>\d+)/$', post_detail, name='post-detail'),
]
#
# 모델 : myapp/models.py
#
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
#
# Serializer : myapp/serializers.py (Form과 유사)
#
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
#
# 뷰 : myapp/views.py
#
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
#
# URL : myapp/urls.py
#
from django.conf.urls import include, path
from rest_framework.routers import DefaultRouter
from .views import PostViewSet
router = DefaultRouter()
router.register('post', PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
import time
from rest_framework.response import Response
from django.core.signals import request_started, request_finished
from .models import Post
from .serializers import PostSerializer
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
def perform_create(self, serializer):
serializer.save(
author=self.request.user,
ip=self.request.META['REMOTE_ADDR'])
def dispatch(self, request, *args, **kwargs):
global cbv
cbv = self
dispatch_start = time.time()
response = super().dispatch(request, *args, **kwargs)
render_start = time.time()
response.render()
self.render_time = time.time() - render_start
self.dispatch_time = time.time() - dispatch_start
self.api_view_time = self.dispatch_time - (self.render_time + self.serializer_time + self.db_time)
return response
def list(self, request, *args, **kwargs):
db_start = time.time()
post_list = list(self.queryset)
self.db_time = time.time() - db_start
serializer_start = time.time()
serializer = self.get_serializer(self.queryset, many=True)
data = serializer.data
self.serializer_time = time.time() - serializer_start
return Response(data)
def started_fn(sender, **kwargs):
global started
started = time.time()
def finished_fn(sender, **kwargs):
request_response_time = (time.time() - started) - cbv.dispatch_time
total = cbv.db_time + cbv.serializer_time + cbv.api_view_time + cbv.render_time + request_response_time
print('Database Lookup - db_time : {:.6f}s, {:>4.1f}%'.format(cbv.db_time, 100*(cbv.db_time/total)))
print('Serialization - serializer_time : {:.6f}s, {:>4.1f}%'.format(cbv.serializer_time, 100*(cbv.serializer_time/total)))
print('API View - api_view_time : {:.6f}s, {:>4.1f}%'.format(cbv.api_view_time, 100*(cbv.api_view_time/total)))
print('Response rendering - render_time : {:.6f}s, {:>4.1f}%'.format(cbv.render_time, 100*(cbv.render_time/total)))
print('Django request/response : {:.6f}s, {:>4.1f}%'.format(request_response_time, 100*(request_response_time/total)))
request_started.connect(started_fn) # 요청 처리 시작
request_finished.connect(finished_fn) # 요청 처리 끝
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment