Tutorial 1: Serialization

7569 ワード

紹介する
このチュートリアルでは、Web APIを強調表示する簡単なpastebinコードを作成する方法について説明します.このプロセスにより,RESTフレームワークを構成する様々なコンポーネントを紹介し,これらがどのように融合しているかを全面的に理解する.
このチュートリアルはかなり深いので、始める前にクッキーとお気に入りの醸造酒を用意しておくべきです.クイック・サマリーのみが必要な場合は、クイック・スタート・ドキュメントに移動します.
注:このチュートリアルのコードはGitHubのtomchristie/rest-framework-tutorialリポジトリで使用できます.完成した実装もオンラインで砂箱バージョンとしてテストされ、ここで入手できます.
新しい環境を構築する
私たちが何かをする前にvirtualenvを使用して新しい仮想環境を作成します.これにより、パッケージ構成が他のプロジェクトと良好に隔離されていることが保証されます.
virtualenv env
source env/bin/activate

今、virtualenv環境で、必要に応じてパッケージをインストールします.
pip install django
pip install djangorestframework
pip install pygments  # We'll be using this for the code highlighting

注意:virtualenv環境をいつでも終了するには、deactivateと入力します.詳細については、virtualenvドキュメントを参照してください.
はじめに
はい、コードを始めるつもりです.まず、作業項目を作成します.
cd ~
django-admin.py startproject tutorial
cd tutorial

完了後、簡単なWEB APIを作成するためにappを作成することができます.
python manage.py startapp snippets

新しいsnippetsアプリケーションとrest_frameworkアプリケーションをINSTALLED_に追加APPS. tutorial/settingsを編集します.pyファイル:
INSTALLED_APPS = (
    ...
    'rest_framework',
    'snippets.apps.SnippetsConfig',
)

Django<1.9を使用する場合は、snippetsをsnippetsに置き換える必要があります.apps.SnippetsConfig.
今準備ができています.
使用可能なモデルの作成
このチュートリアルの目的は、コードクリップを格納するための簡単なSnippetモデルを作成することです.snippets/modelsの編集を続行します.pyファイル.注意:良いプログラミング実践にはコメントが含まれています.このチュートリアル・コードのバージョン・ライブラリでチュートリアル・コードを見つけますが、コード自体に焦点を当てて無視します.
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',)

また、snippetモデルの初期移行を作成し、データベースを初めて同期する必要があります.
python manage.py makemigrations snippets
python manage.py migrate

シーケンス化クラスの作成
まず、Web APIを開始する必要がある最初のことは、snippetインスタンスをjsonのような形式にシーケンス化し、逆シーケンス化する方法を提供することである.Djangoフォームと非常に似たシーケンス化器を宣言して実装することができます.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

シーケンサクラスの第1部では、シーケンサ/逆シーケンサのフィールドを定義します.create()とupdate()メソッドはserializerを呼び出すことを定義する.save()の場合、完全なインスタンスを作成または変更する方法.
シーケンサクラスはDjango Formクラスとよく似ており、required,max_などの類似の検証フラグが様々なフィールドに含まれています.lengthとdefault.場合によっては、フィールドフラグは、HTMLレンダリングなどのシーケンス化の表示方法を制御することもできます.フィールドフラグは、HTMLレンダリング時にシリアルをどのように表示するかなど、場合によっては制御することもできます.上の{'base_template':'textarea.html'}フラグはDjango Formクラスでwidget=widgetsを使用するのと同じです.Textarea. これは、ブラウズ可能なAPIの表示方法を制御するのに特に役立ちます.このチュートリアルの後で説明します.
シーケンス化の使用
さらに理解する前に、新しいSerializerクラスの使用を熟知します.Django shellに入りましょう.
python manage.py shell

はい、いくつかのインポートがあれば、snippetsを作成して処理します.
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()

私たちは今いくつかのsnippetインスタンスが游ぶことができます.これらのインスタンスのシーケンス化の1つを見てみましょう.
serializer = SnippetSerializer(snippet)
serializer.data
# {'id': 2, 'title': u'', 'code': u'print "hello, world"
', 'linenos': False, 'language': u'python', 'style': u'friendly'}

このとき,モデルインスタンスをPythonオリジナルデータ型に変換する.データをjsonに転送し、シーケンス化プロセスを完了します.
content = JSONRenderer().render(serializer.data)
content
# '{"id": 2, "title": "", "code": "print \\"hello, world\\"\
", "linenos": false, "language": "python", "style": "friendly"}'

逆シーケンス化は似ています.まず、Pythonのオリジナルデータ型としてストリームを解析します.
from django.utils.six import BytesIO

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

...次に、これらのオリジナルデータ型をオブジェクトインスタンスに復元します.
serializer = SnippetSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# OrderedDict([('title', ''), ('code', 'print "hello, world"
'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]) serializer.save() #

APIがフォームとともにどのように使用されるかに注意してください.serializerを使用してviewsを記述し始めると、類似性がより顕著になるはずです.
モデルインスタンスではなくquerysetsをシーケンス化することもできます.これを行うには、serializerパラメータにmany=Trueのフラグを追加するだけです.
serializer = SnippetSerializer(Snippet.objects.all(), many=True)
serializer.data
# [OrderedDict([('id', 1), ('title', u''), ('code', u'foo = "bar"
'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', u''), ('code', u'print "hello, world"
'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]