Django REST FrameWork中国語教程1:シーケンス化
15164 ワード
紹介する
このチュートリアルでは、簡単なPasteBin 1コードでハイライトされたWeb APIについて説明します.プロセス全体で、REST frameworkの各構成部品を一つ一つ紹介し、コンポーネント間がどのように統合されているかを全面的に理解させます.
このチュートリアルは少し深いので、始める前に、クッキーを何枚か必要として、お気に入りの飲み物を1杯食べながら見るかもしれません.クイック・スタート・ドキュメントに移動するには、クイック・スタート・ドキュメントに移動します.
注:このチュートリアルのコードは、GitHubのtomchristie/rest-framework-tutorialリポジトリにあります.完成した実装もオンラインで砂箱バージョンとしてテストされ、ここで見つけることができます.
新しい環境を構築する
私たちが何かをする前にvirtualenvを使用して新しい仮想環境を作成します.これにより、パッケージ構成が他のプロジェクトと良好に隔離されていることが保証されます.
これでvirtualenv環境に入り、必要なソフトウェアサポートパッケージのインストールを開始できます.
開始の準備
はい、コードを用意しました.まず、新しいプロジェクト(project)を作成して処理しましょう.
その後、appアプリケーションを作成して、簡単なWeb APIを作成することができます.
新しいsnippetsアプリケーションとrest_frameworkアプリケーションをINSTALLED_に追加APPS. tutorial/settingsを編集します.pyファイル:
Django<1.9を使用する場合は、snippetsを交換する必要があります.apps.SnippetsConfigにはsnippetsがあります.
はい、準備はできました.
使用可能なモデルの作成(model)
チュートリアルの設計を考慮して、まず簡単な
Python
また、snippetモデルのデータのテーブルを作成し、モデルをデータベースに同期し、初期の移行(migration)を実現する必要があります.
シーケンス化Serializerクラスの作成
我々のWeb APIは、コードフラグメントのインスタンス(instances)にシーケンス化および逆シーケンス化の経路を提供し、
Python
シーケンサ(
シーケンサクラスはDjangoのFormクラスに非常に類似しており、複数のフィールドには、
フィールド識別(flag)もできます.シーケンサを制御し、特定の場合、HTMLにレンダリング(rendering)する必要があるなど、どのように表示(displayed)されるかを制御します.上の
実際には、
Serializer****の使用
さらに理解する前に、新しいSerializerクラスの使用を熟知します.Django shellに入りましょう.
shell端末に入ったら、次のコードを入力します.
使用可能なコードフラグメントのいくつかのインスタンスがあります.シーケンス化の1つのインスタンスを見てみましょう.
ここで,モデルインスタンスをPythonのオリジナルデータ型(native datatypes)に変換した.シーケンス化のプロセスを完了するには、dataを
逆シーケンス化は似ています.まず、ストリームをPythonデータ型に解析します.
次に、このオリジナルデータ型をオブジェクトインスタンスに変換します.
APIの動作形式はこのように似ていることに注意してください.このような繰返し性の類似は,我々のビュー(
モデルインスタンスに加えてquerysetをシーケンス化することもできます.シーケンサのパラメータに
ModelSerializersの使用
Djangoが
どのように
シーケンス化プログラムには、シーケンス化されたプロパティを印刷する機能があります.シーケンサオブジェクトのすべてのフィールドを表示します.Django shell(すなわち
注意:フィールドのセットが自動的に宣言されました デフォルトの実装 我々のSerializerを使用して通常のDjangoビューを作成
新しいSerializerクラスを使用してAPIビューを作成する方法を見てみましょう.これまでREST frameworkの他の特性を使用したことはありませんが、一般的なDjangoビューを作成しただけです.
HttpResponseのサブクラスを作成することから始めます.このサブクラスは、任意のdataをレンダリングし、
我々のAPIのルートurlは、既存のすべてのコードクリップを表示したり、新しいコードクリップを作成したりするビューになります.
Python
なお、このビューのクライアントにはCSRFトークン(token)がないPOSTデータが必要であるため、ビューに
また、個別のコードクリップに応答し、このクリップを取得、更新、削除するビューも必要です.
Python
最後に、これらのビューを登録する必要があります.作成
また、
注意すべきは、現在、いくつかのエッジイベント(edge cases)があり、対応する処理はありません.乱雑な
Web APIでの最初のアクセスをテスト
コードフラグメントをサービスするサンプルサーバを起動できます.
Django shellを終了...
Djangoの開発サーバを起動します.
別の端末を起動して、サーバをテストすることができます.
curlまたはhttpieを使用して、APIをテストすることができます.HttpieはPythonで書かれたユーザーフレンドリーなhttpクライアントです.
pipを使用してhttpieをインストールできます.
最後に、すべてのクリップのリストを得ることができます.
または、idを参照して特定のコードセグメントを取得できます.
同様に、WebブラウザでこれらのURLにアクセスすることで、同じjsonを表示できます.
今どこにいるの?
これまではまあまあでしたが、シーケンス化されたAPIはDjangoのFormAPIと似ていると感じ、一般的なDjangoビューをいくつか作りました.
私たちのAPIビューは、まだ特別なことをしていません.jsonに応答したほか、処理できなかったエッジイベントもいくつかあるが、少なくとも使えるWeb APIである.
このチュートリアルの第2部では、改善を開始する方法について説明します.
テキストアドレス
このチュートリアルでは、簡単なPasteBin 1コードでハイライトされたWeb APIについて説明します.プロセス全体で、REST frameworkの各構成部品を一つ一つ紹介し、コンポーネント間がどのように統合されているかを全面的に理解させます.
このチュートリアルは少し深いので、始める前に、クッキーを何枚か必要として、お気に入りの飲み物を1杯食べながら見るかもしれません.クイック・スタート・ドキュメントに移動するには、クイック・スタート・ドキュメントに移動します.
注:このチュートリアルのコードは、GitHubのtomchristie/rest-framework-tutorialリポジトリにあります.完成した実装もオンラインで砂箱バージョンとしてテストされ、ここで見つけることができます.
新しい環境を構築する
私たちが何かをする前にvirtualenvを使用して新しい仮想環境を作成します.これにより、パッケージ構成が他のプロジェクトと良好に隔離されていることが保証されます.
virtualenv
envsource env/bin/activate
これでvirtualenv環境に入り、必要なソフトウェアサポートパッケージのインストールを開始できます.
pip install django
pip install djangorestframework
pip install pygments #
注意:virtualenv環境をいつでも終了するには、deactivate
を入力します.詳細については、virtualenvドキュメントを参照してください.開始の準備
はい、コードを用意しました.まず、新しいプロジェクト(project)を作成して処理しましょう.
cd ~
django-admin.py startproject tutorial
cd tutorial
その後、appアプリケーションを作成して、簡単なWeb APIを作成することができます.
python manage.py startapp snippets
新しいsnippetsアプリケーションとrest_frameworkアプリケーションをINSTALLED_に追加APPS. tutorial/settingsを編集します.pyファイル:
INSTALLED_APPS = (
...
'rest_framework',
'snippets.apps.SnippetsConfig',
)
Django<1.9を使用する場合は、snippetsを交換する必要があります.apps.SnippetsConfigにはsnippetsがあります.
はい、準備はできました.
使用可能なモデルの作成(model)
チュートリアルの設計を考慮して、まず簡単な
Snippet
モデルを作成します.関連コードを格納し、snippets/models.py
ファイルを編集します.注意:良いプログラミングの実践には注釈があります.このチュートリアルのサンプルコードではコメントを見つけることができますが、ここではコメントを省略します.Python
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モデルのデータのテーブルを作成し、モデルをデータベースに同期し、初期の移行(migration)を実現する必要があります.
python manage.py makemigrations snippets
python manage.py migrate
シーケンス化Serializerクラスの作成
我々のWeb APIは、コードフラグメントのインスタンス(instances)にシーケンス化および逆シーケンス化の経路を提供し、
json
のような表現形式に変換できるようにすることから始まる.Djangoフォーム(form)の動作と同様に、宣言シーケンサ(serializer)を使用して実現できます.snippets
パスの下で、ファイルserializers.py
を作成し、以下の内容を指定します.Python
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
class SnippetSerializer(serializers.Serializer):
# serializer, Django Form json
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):
"""
, `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
シーケンサ(
serializer
)クラスの第1部は、RESTフレームワークに、どのフィールド(field)がシーケンス化/逆シーケンス化される必要があるかを示す.create()
メソッドおよびupdate()
メソッドは、コンテンツのあるインスタンスオブジェクトを作成および変更する方法を定義します.この2つのメソッドは、serializer.save()
を実行すると呼び出されます.シーケンサクラスはDjangoのFormクラスに非常に類似しており、複数のフィールドには、
required
、max_length
およびdefault
などの類似の検証識別子も含まれている.フィールド識別(flag)もできます.シーケンサを制御し、特定の場合、HTMLにレンダリング(rendering)する必要があるなど、どのように表示(displayed)されるかを制御します.上の
{'base_template': 'textarea.html'}
識別子は、DjangoのFormクラスでwidget=widgets.Textarea
を使用することに相当する.これは、特に、可視化されたAPIがどのようにレンダリングされるかを制御する場合に有用である.私たちは後のチュートリアルで、この点を見ることができます.実際には、
ModelSerializer
クラスをどのように使用して時間を節約するかを見ることができます.しかし、シーケンサでは、各フィールドの明確な定義を維持します.Serializer****の使用
さらに理解する前に、新しいSerializerクラスの使用を熟知します.Django shellに入りましょう.
python manage.py shell
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()
使用可能なコードフラグメントのいくつかのインスタンスがあります.シーケンス化の1つのインスタンスを見てみましょう.
###
snippet ,
snippet = Snippet(code='print "hello, world"
')
snippet.save()
###
serializer = SnippetSerializer(snippet)
serializer.data
# {'id': 2, 'title': u'', 'code': u'print "hello, world"
', 'linenos': False, 'language': u'python', 'style': u'friendly'}
ここで,モデルインスタンスをPythonのオリジナルデータ型(native datatypes)に変換した.シーケンス化のプロセスを完了するには、dataを
json
にレンダリングします.# json
content = JSONRenderer().render(serializer.data)
content
# '{"id": 2, "title": "", "code": "print \\"hello, world\\"\
", "linenos": false, "language": "python", "style": "friendly"}'
逆シーケンス化は似ています.まず、ストリームをPythonデータ型に解析します.
# json
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の動作形式はこのように似ていることに注意してください.このような繰返し性の類似は,我々のビュー(
view
)ではシーケンスを用いると,より顕著になる.モデルインスタンスに加えてquerysetをシーケンス化することもできます.シーケンサのパラメータに
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')])]
ModelSerializersの使用
SnippetSerializer
クラスでは、Snippet
モデルのフィールド定義で多くのことが繰り返されます.コードを簡潔に保つことができれば、いいのではないでしょうか.Djangoが
Form
クラスを提供し、ModelForm
クラスも提供し、REST frameworkにもSerializer
クラスとModelSerializer
クラスがあります.どのように
ModelSerializer
クラスを使用して、私たちのシーケンサを再構築するかを見てみましょう.snippets/serializersを再度開きます.py,SnippetSerializer
クラスを次のように置き換えます.class SnippetSerializer(serializers.ModelSerializer):
# ModelSerializer Django ModelForm
# Serializer Django Form
class Meta:
model = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
シーケンス化プログラムには、シーケンス化されたプロパティを印刷する機能があります.シーケンサオブジェクトのすべてのフィールドを表示します.Django shell(すなわち
python manage.py shell
)で試してみましょう.from snippets.serializers import SnippetSerializer
serializer = SnippetSerializer()
print(repr(serializer))
# 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)
# language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')...
# style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')...
注意:
ModelSerializer
クラスは特に不思議なことはしません.シーケンス化器クラスを作成するショートカットにすぎません.create()
およびupdate()
メソッド新しいSerializerクラスを使用してAPIビューを作成する方法を見てみましょう.これまでREST frameworkの他の特性を使用したことはありませんが、一般的なDjangoビューを作成しただけです.
HttpResponseのサブクラスを作成することから始めます.このサブクラスは、任意のdataをレンダリングし、
json
に戻ります.snippets/views.py
ファイルを編集し、次の内容を追加します.from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
我々のAPIのルートurlは、既存のすべてのコードクリップを表示したり、新しいコードクリップを作成したりするビューになります.
Python
@csrf_exempt
def snippet_list(request):
"""
List all code snippets, or create a new snippet.
"""
if request.method == 'GET':
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = SnippetSerializer(data=data)
if serializer.is_valid():
serializer.save()
# serializer.data
return JsonResponse(serializer.data, status=201)
# serializer.errors
return JsonResponse(serializer.errors, status=400)
なお、このビューのクライアントにはCSRFトークン(token)がないPOSTデータが必要であるため、ビューに
csrf_exempt
とマークする必要がある.あなたは普段そんなことはしませんが、実際には、これよりもREST frameworkのビューの方が合理的な行為をしていますが、今はそうします.また、個別のコードクリップに応答し、このクリップを取得、更新、削除するビューも必要です.
Python
@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)
最後に、これらのビューを登録する必要があります.作成
snippets/urls.py
ファイル:from django.conf.urls import url
from snippets import views
urlpatterns = [
url(r'^snippets/$'>, views.snippet_list),
url(r'^snippets/(?P[0-9]+)/$'>, views.snippet_detail),
]
また、
tutorial/urls.py
ファイルのルートurl構成(root urlconf)に登録して、snippets appのURLsを含める必要があります.from django.conf.urls import url, include
urlpatterns = [
url(r'^', include('snippets.urls')),
]
注意すべきは、現在、いくつかのエッジイベント(edge cases)があり、対応する処理はありません.乱雑な
json
を送信したり、要求が要求方法を使用したりして、modifyなどのビューに含まれていない場合、500「server error」の応答(response)が表示されます.とにかく、今私たちはしばらくそうします.Web APIでの最初のアクセスをテスト
コードフラグメントをサービスするサンプルサーバを起動できます.
Django shellを終了...
quit()
Djangoの開発サーバを起動します.
python manage.py runserver
Validating models...
0 errors found
Django version 1.11, using settings 'tutorial.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
別の端末を起動して、サーバをテストすることができます.
curlまたはhttpieを使用して、APIをテストすることができます.HttpieはPythonで書かれたユーザーフレンドリーなhttpクライアントです.
pipを使用してhttpieをインストールできます.
pip install httpie
最後に、すべてのクリップのリストを得ることができます.
http http://127.0.0.1:8000/snippets/
HTTP/1.1 200 OK...
[
{
"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を参照して特定のコードセグメントを取得できます.
http http://127.0.0.1:8000/snippets/2/
HTTP/1.1 200 OK
...
{
"id": 2,
"title": "",
"code": "print \"hello, world\"
",
"linenos": false,
"language": "python",
"style": "friendly"
}
同様に、WebブラウザでこれらのURLにアクセスすることで、同じjsonを表示できます.
今どこにいるの?
これまではまあまあでしたが、シーケンス化されたAPIはDjangoのFormAPIと似ていると感じ、一般的なDjangoビューをいくつか作りました.
私たちのAPIビューは、まだ特別なことをしていません.jsonに応答したほか、処理できなかったエッジイベントもいくつかあるが、少なくとも使えるWeb APIである.
このチュートリアルの第2部では、改善を開始する方法について説明します.
テキストアドレス