Python – postgresql – Django – REST – TensorFlow 서비스 개발(2)

가. 지금까지 완료 된 것

– 1부 링크  : http://wp.me/p7xrpI-9h

– Anaconda 설치
– TensorFlow 설치
– Pycharm 설치
– postgresql 설치
– Django 설치
– Django Service 생성
– snippets APP 생성 완료
– Snippet Model 생성
– postgresql  동기화 완료

나.  Serializer

우리가 위에서 정의한  Snippet 데이터 클레스를 받아서  JSON 데이터로 변환하거나 ,
그 반대를 수행하는 클래스라고 생각하면 된다. 아래와 같이 프로젝트에 파일을 추가하고
콘솔을 실행하여 몇 가지 예를 테스트해보면 더 이해가 용이할 것이이다.

[Serializer 생성]

스크린샷, 2016-08-25 04-33-37

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


class SnippetSerializer(serializers.Serializer):
    pk = 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

 

[테스트 결과]

스크린샷, 2016-08-25 04-42-05

[디장고 쉘 실행]

python manage.py shell

 

[디비에 데이터 두건 삽입]

from snippets.models importSnippetfrom snippets.serializers importSnippetSerializerfrom rest_framework.renderers importJSONRendererfrom rest_framework.parsers importJSONParser snippet =Snippet(code='foo = "bar"\n') snippet.save() snippet =Snippet(code='print "hello, world"\n') snippet.save()

 

[정렬된 파이선 기본 데이터 타입]

serializer =SnippetSerializer(snippet) serializer.data

ReturnDict([('pk', None),
            ('title', u''),
            ('code', u'foo = "bar"\n'),
            ('linenos', False),
            ('language', 'python'),
            ('style', 'friendly')])

 

[정렬된 파이선 데이터를 JSON으로 변환]

content =JSONRenderer().render(serializer.data) content

'[{"pk":1,"title":"","code":"foo = \\"bar\\"\\n","linenos":false,"language":"python","style":"friendly"},{"pk":2,"title":"","code":"print \\"hello, world\\"\\n","linenos":false,"language":"python","style":"friendly"}]'

 

[JSON 파싱]

from django.utils.six importBytesIO stream =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>

 

[현재 디비에 저장된 모든 항목 출력]

serializer =SnippetSerializer(Snippet.objects.all(), many=True) serializer.data

Out[34]: [OrderedDict([('pk', 1), ('title', u''), ('code', u'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 2), ('title', u''), ('code', u'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]

 

다. ModelSerializer 사용

위에서 정의한 꽤나 긴 Serialzier Code 를 아래와 같이 단순화 할 수 있다

class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')

 

라.  views.py

실제로 서비스를 제공할 로직을 구현한다. 아래의 예제는  snippet_list 와  snippet_detail
두 가지 서비스에 대한 코드로 호출 주소에 대한 규칙은  urls.py 에 정의한다.
그리고 해당 메서드를 rest 로 정의하는 코드는 @api_view 로 처리하고자 하는 CRUD
를 정의하고 분기하여 처리한다.

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer



@api_view(['GET', 'POST'])
def snippet_list(request, format=None):
    """
    List all snippets, or create a new snippet.
    """
    if request.method == 'GET':
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, pk, format=None):
    """
    Retrieve, update or delete a snippet instance.
    """
    try:
        snippet = Snippet.objects.get(pk=pk)
    except Snippet.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = SnippetSerializer(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

 

마. urls.py

from django.conf.urls import url
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^snippets/$', views.snippet_list),
    url(r'^snippets/(?P<pk>[0-9]+)$', views.snippet_detail),
]

urlpatterns = format_suffix_patterns(urlpatterns)

 

바. TEST

[snippet_list]

http http://127.0.0.1:8000/snippets/ Accept:application/json

스크린샷, 2016-08-25 06-38-41

[snippet_detail]

http form POST http://127.0.0.1:8000/snippets/ code=”print 123″

스크린샷, 2016-08-25 06-38-59

사. Class Based View

위 의 예제는 annotation 을 지정하여 사용하는 전형적인 REST 서버의 모습이었다고 하면, 클래스 형태로  REST  서비스를 구성하는 패턴도 있다

[views.py]

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status


class SnippetList(APIView):
    """
    List all snippets, or create a new snippet.
    """
    def get(self, request, format=None):
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 

class SnippetDetail(APIView): """ Retrieve, update or delete a snippet instance. """ def get_object(self, pk): try: return Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: raise Http404 def get(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet) return Response(serializer.data) def put(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk, format=None): snippet = self.get_object(pk) snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)

 

[urls.py]

from django.conf.urls import url
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^snippets/$', views.SnippetList.as_view()),
    url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

 

Leave a Reply

Your email address will not be published. Required fields are marked *