Django-rest-framework学習(-)Serialization


Django-rest-framework学習(-)Serialization
ラベル(スペース区切り):インターネットAPI Django
  • Django-rest-framework学習Serialization
  • 前提条件
  • 仮想環境構築
  • 対応するパッケージ
  • をインストール

  • が本格的にスタート
  • モデル作成
  • serializerクラス
  • を作成
  • 逆シーケンス化
  • 内蔵モデルシーケンスクラスModelSerializers
  • を使用
  • serializerを使用してviewsと結合する

  • まとめ


  • 前提条件
    Python (2.7, 3.2, 3.3, 3.4, 3.5) Django (1.7+, 1.8, 1.9)
    仮想環境構築
        pip install virtualenv
        virtualenv frankstar        //                                     
        cd frankstar
        source ./bin/activate  //       
        deactivate   //       
        (frankstar) ➜  frankstar

    対応するパッケージのインストール
    1)                   ,  
        pip install -r <filename>     
       : requirements.txt
        django == 1.8.0
        djangorestframework
        pygments
        mysql-python == 1.2.52

    本番
        django-admin.py startproject tutorial
        cd tutorial
        python manage.py startapp snippets

    私たちのアプリケーションsnippetsとrest-frameworkを自分のプロファイルにINSTALLED_に追加する必要があります.APPSは以下の通り:
        INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'snippets.apps.SnippetsConfig',
        'rest_framework',
    )

    ついでにデータベースの構成も追加します.以下のようにします.
        DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'tutorial',
                'USER': 'root',
                'PASSWORD': '',
                'HOST': '127.0.0.1',
                'PORT': '3306',
            }
        }

    モデルの作成
    # coding:utf-8
    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):
        """docstring for Snippet"""
        #               
        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',)
    

    次のコマンドを実行します.
        python manage.py makemigrations snippets //    snippets
        python manage.py migrate   //                

    serializerクラスの作成
    Web APIを提供する場合、インスタンスオブジェクトを対応するデータフォーマット、シーケンス化、または逆シーケンス化に変換する必要があります.Djangoフレームワークには実はこの機能を持つライブラリがあり、まずこのようなクラスを作成してみましょう.snippetsフォルダの下にserializers.pyというファイルを作成します.定義は次のとおりです.
    #coding:utf-8
    
    from rest_framework import serializers
    from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
    
    class SnippetSerializer(serializers.Serializer):
        """docstring for SnippetSerializer"""
        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):
            '''                 Snippet   '''
            return Snippet.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            '''                 Snippet   '''
            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
    

    Djangoのshellを開き、いくつかのSnippetインスタンスを作成してみます
        python manage.py shell
    
        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"
    '
    ) snippet.save() snippet = Snippet(code='print "hello, world"
    '
    ) snippet.save()

    次に、このクラスに作成されたシーケンス化クラスSnippetSerializerを呼び出し、jsonオブジェクトを出力します.
        serializer = SnippetSerializer(snippet)
        serializer.data
        #output: {'style': 'friendly', 'code': u'print "hello,world"
    '
    , 'language': 'python', 'title': u'', 'linenos': False, 'pk': 2} content = JSONRenderer().render(serializer.data) content #output: '{"pk":2,"title":"","code":"print \\"hello,world\\"\
    "
    ,"linenos":false,"language":"python","style":"friendly"}'

    逆シーケンス化
    逆シーケンス化も同様の処理であり,前述の手順に続くかDjango shellで処理するかである.
        from django.utils.six import BytesIO
    
        stream = BytesIO(content)
        data = JSONParser.parse(stream)
        serializer = SnippetSerializer(data=data)
        serializer.is_valid()  //        json  
        #output: True
    
        serializer.validate_data
        #output: OrderedDict([(u'title', u''), (u'code', u'print "hello,world"'), (u'linenos', False), (u'language', 'python'), (u'style', 'friendly')]) serializer.save() #output: <Snippet: Snippet object> 

    複数のSnippetインスタンスを同時に処理することができ、その構築方法にmany=Trueというパラメータを加えるだけで、以下のようにすることができます.
        serializer = SnippetSerializer(Snippet.objects.all(), many=True)
        serializer.data
        #output: [OrderedDict([('pk', 1), ('title', u''), ('code', u'foo = "bar"
    '
    ), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 2), ('title', u''), ('code', u'print "hello,world"
    '
    ), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 3), ('title', u''), ('code', u'print "hello,world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]

    組み込みモデルシーケンスクラスModelSerializersの使用
    serializer.pyを開き、SnippetSerializerクラス定義の場所(create()とupdate()メソッドはしばらく変更する必要はありません)を見つけ、次のコードに変更します.
        class SnippetSerializer(serializers.ModelSerializer):
        """docstring for SnippetSerializer"""
       #                       
            class Meta:
                model = Snippet
                fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
    

    django manage.py shellを開いて次のコマンドを入力します.
        from snippets.serializers import SnippetSerializer
    
        serializer = SnippetSerializer()
        print(repr(serializer))
        #output: SnippetSerializer():
        id = IntegerField(label='ID', read_only=True)
        title = CharField(allow_blank=True, max_length=100, required=False)
        code = CharField(style={'base_template': 'textarea.html'})
        linenos = BooleanField(required=False)
        ...

    serializerを使用してviewsと結合
    まずsnippetsファイルの下にファイルviews.pyを新規作成し、次のコードを作成します.
        #coding:utf-8
        from django.shortcuts import render
        from django.views.decorators.csrf import csrf_exempt
        from django.http import HttpResponse
        from rest_framework.renderers import JSONRenderer
        from rest_framework.parsers import JSONParser
        from snippets.models import Snippet
        from snippets.serializers import SnippetSerializer
        # Create your views here.
    
        class JSONResponse(HttpResponse):
            """docstring for JSONRenderer"""
            '''  HttpResponse          json '''
            def __init__(self, data, **kwargs):
                content = JSONRenderer().render(data)
                kwargs['content_type'] = 'application/json'
                super(JSONResponse, self).__init__(content, **kwargs)
    
    
        @csrf_exempt
        def snippet_list(request):
            '''      snippets   ,           '''
            if request.method == 'GET':
                snippets = Snippet.objects.all()
                serializers = SnippetSerializer(snippets, many=True)
    
                return JSONResponse(serializers.data)
    
            elif request.method == 'POST':
                data = JSONParser().parse(request)
                serializers = SnippetSerializer(data=data)
                if serializers.is_valid():
                    serializers.save()
    
                    return JSONResponse(serializers.data, status=201)
                return JSONResponse(serializers.errors, status=400)
    
        @csrf_exempt
        def snippet_detail(request, pk):
            '''   、        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)
    

    次に、フォルダ(snippets)の下にurls.pyというファイルを追加し、アクセスルーティングを配置します.
        #coding:utf-8
        from django.conf.urls import url
        from snippets import views
    
        urlpatterns = [
            url(r'^snippets/$', views.snippet_list),
            url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),
        ]

    最後に、次のように変更ルーティングファイルを総ルーティングファイルに追加します.
        from django.conf.urls import include, url
        from django.contrib import admin
    
        urlpatterns = [
            # Examples:
            # url(r'^$', 'tutorial.views.home', name='home'),
            # url(r'^blog/', include('blog.urls')),
    
            url(r'^admin/', include(admin.site.urls)),
    
            url(r'^', include('snippets.urls')), #        
        ]

    コマンドラインを開き、python manage.py runserverと入力します.ブラウザに次のように入力します.http://127.0.0.1:8000/snippets/、出力は次のとおりです.
    [
        {
            id: 1,
            title: "",
            code: "foo = "bar" ",
            linenos: false,
            language: "python",
            style: "friendly"
        },
        {
            id: 2,
            title: "",
            code: "print "hello,world" ",
            linenos: false,
            language: "python",
            style: "friendly"
        },
        {
            id: 3,
            title: "",
            code: "print "hello,world"",
            linenos: false,
            language: "python",
            style: "friendly"
        }
    ]

    具体的なIDを入力し、次のような具体的な内容を表示することもできます.http://127.0.0.1:8000/snippets/2/、出力は次のとおりです.
        { id: 2, title: "", code: "print "hello,world" ", linenos: false, language: "python", style: "friendly" }

    まとめ
    このケースは公式サイトから見つけることができて、これはただその中の1つの部分で、先頭に立って、後続の会は不定期に補充して、細心の注意を払う人はsnippet_listとsnippet_detailインタフェース定義では、PUT、DELETE、GET、POSTなどのHttpメソッドがありますが、対応するルーティングにはrestful-apiのいくつかの知識に関するレコードが1つしかありません.同じルートであるが,呼び出されるHttpメソッドが異なるため,当然同じルートではない.