Django REST framework学習紀要Tutorial 1 Serialization
13596 ワード
に頼る Python 3.6.3[Python(2.7,3.2,3.3,3.4,3.5,3.6)どちらでもよい] Django 1.11.7[Django(1.10,1.11,2.0 alpha)どちらでもよい] 仮想環境のインストール、作成、構成仮想環境Pythonバージョン管理ツールPyenvのインストールと使用 仮想環境の作成 関連パッケージ をインストール
Djangoプロジェクト初期化 を作成する. .
Modelの作成
コードフラグメントを格納するために修正 データベース移行
Serializerクラスの作成 を作成する.
Serializersクラスの使用 Django shell を開く Serializersオブジェクトを2つ作成
シーケンス化オブジェクトをシーケンス化する dataデータを に変換する.
逆シーケンス化 JSONデータをPython生データ型(辞書) に変換 Pythonオリジナルデータ型(辞書)をオブジェクト に変換する.は、 を追加するだけでクエリーセットをシーケンス化することができる.
ModelSerializerの使用
先ほど定義したは、 Django shell を開く を表示
これにより,クラス属性 を繰り返し定義する必要はない.自動所有 SerializerのDjango views内での簡単な運用ここではREST frameworkの他の特性は使用されず、従来のDjango views のみが使用される.ここでの書き方には多くの抜け穴があり、チュートリアルのテスト展示としてのみ使用され、本番環境 に直接適用することはできません.
viewsの構成関連パッケージ をインポートする.すべてのオブジェクトとオブジェクトの追加機能を返すAPI を作成するオブジェクトの検索、変更、削除機能を作成するAPI
urlsの構成作成 配置項目根
テストインタフェースサービス を開始別のshellウィンドウ を開くは、http要求 をシミュレートするためのは要求を送信し、すべてのsnippetsオブジェクト を取得する.は要求を送信し、プライマリキーが2のsnippetsオブジェクト を取得する.
について
私は初めてDjango REST frameworkを学んで、Django REST framework学習紀要シリーズの文章は私が公式サイトのドキュメントから学習した後の初歩的な消化の成果で、もし間違いがあれば、指摘を歓迎します.
学習用コードGithubウェアハウス:shelmingsong/django_rest_framework
参考になる公式サイトのドキュメント:Tutorial 1:Serialization
ブログ更新アドレス宋明耀のブログ[第1時間更新] コラムPython Cookbook 流月0の文章
mkdir django_rest_framework && cd django_rest_framework
pyenv virtualenv 3.6.3 django_rest_framework
pyenv local django_rest_framework
pip install django djangorestframework
pip install pygments # ,
Djangoプロジェクト初期化
tutorial
プロジェクトとsnippets
アプリケーションdjango-admin startproject tutorial
cd tutorial/
python manage.py startapp snippets
snippets
アプリケーションおよびrest_framework
をsettings.py
のINSTALLED_APPS
に追加する(Djangoバージョンが1.9未満の場合、snippets.apps.SnippetsConfig
をsnippets
に置き換える必要がある)INSTALLED_APPS = (
...
'rest_framework',
'snippets.apps.SnippetsConfig',
)
Modelの作成
コードフラグメントを格納するために
Snippet
モデルを作成する必要があります.snippets/models.py
ファイルfrom django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
# pygments
LEXERS = [item for item in get_all_lexers() if item[1]]
# pygments
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
# pygments
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',)
python manage.py makemigrations snippets
python manage.py migrate
Serializerクラスの作成
snippets
フォルダ内にserializers.py
ファイルfrom rest_framework import serializers
from snippets.models import LANGUAGE_CHOICES
from snippets.models import Snippet
from snippets.models import 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
Serializersクラスの使用
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()
シーケンス化
In [11]: serializer = SnippetSerializer(snippet)
In [12]: serializer.data
Out[12]:
ReturnDict([('id', 2),
('title', ''),
('code', 'print "hello, world"
'),
('linenos', False),
('language', 'python'),
('style', 'friendly')])
json
In [13]: content = JSONRenderer().render(serializer.data)
In [14]: content
Out[14]: b'{"id":2,"title":"","code":"print \\"hello, world\\"\
","linenos":false,"language":"python","style":"friendly"}'
逆シーケンス化
In [15]: from django.utils.six import BytesIO
In [16]: stream = BytesIO(content)
In [17]: data = JSONParser().parse(stream)
In [18]: data
Out[18]:
{'code': 'print "hello, world"
',
'id': 2,
'language': 'python',
'linenos': False,
'style': 'friendly',
'title': ''}
In [19]: serializer = SnippetSerializer(data=data)
In [20]: serializer.is_valid()
Out[20]: True
In [21]: serializer.validated_data
Out[21]:
OrderedDict([('title', ''),
('code', 'print "hello, world"'),
('linenos', False),
('language', 'python'),
('style', 'friendly')])
In [22]: serializer.save()
Out[22]:
many=True
パラメータIn [23]: serializer = SnippetSerializer(Snippet.objects.all(), many=True)
In [24]: serializer.data
Out[24]: [OrderedDict([('id', 1), ('title', ''), ('code', 'foo = "bar
"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', ''), ('code', 'print "hello, world"
'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', ''), ('code', 'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]
ModelSerializerの使用
先ほど定義した
SnippetSerializer
クラスのクラスの多くは、models.py
で定義した内容と重複していますが、SnippetSerializer
クラスをModelSerializer
に継承して、このような重複定義を減らすこともできます.SnippetSerializer
クラスを次のように再定義する:class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
python manage.py shell
SnippetSerializer
クラスIn [1]: from snippets.serializers import SnippetSerializer
In [2]: serializer = SnippetSerializer()
In [3]: 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=[('abap', 'ABAP'), ('abnf', 'ABNF'), ('ada', 'Ada'), ('adl', 'ADL'), ('agda', 'Agda'), ('aheui', 'Aheui'), ('ahk', 'autohotkey'),
...
これにより,
ModelSerializer
クラスに継承され,2つの非常に大きな役割を果たすことが分かった.create()
およびupdate()
メソッドviewsの構成
snippets/views.py
を開くfrom django.shortcuts import render
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
@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()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
@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)
urlsの構成
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),
]
urls.py
from django.conf.urls import url
from django.conf.urls import include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('snippets.urls')),
]
テストインタフェース
(django_rest_framework) [root@localhost tutorial]# python manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
November 20, 2017 - 23:01:29
Django version 1.11.7, using settings 'tutorial.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
httpie
パケットをインストールする.pip install httpie
(django_rest_framework) [root@localhost tutorial]# http http://127.0.0.1:8000/snippets/
HTTP/1.0 200 OK
Content-Length: 352
Content-Type: application/json
Date: Mon, 20 Nov 2017 15:03:10 GMT
Server: WSGIServer/0.2 CPython/3.6.3
X-Frame-Options: SAMEORIGIN
[
{
"code": "foo = \"bar
\"",
"id": 1,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
},
{
"code": "print \"hello, world\"
",
"id": 2,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
},
]
(django_rest_framework) [root@localhost tutorial]# http http://127.0.0.1:8000/snippets/2/
HTTP/1.0 200 OK
Content-Length: 119
Content-Type: application/json
Date: Mon, 20 Nov 2017 15:03:17 GMT
Server: WSGIServer/0.2 CPython/3.6.3
X-Frame-Options: SAMEORIGIN
{
"code": "print \"hello, world\"
",
"id": 2,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
}
について
私は初めてDjango REST frameworkを学んで、Django REST framework学習紀要シリーズの文章は私が公式サイトのドキュメントから学習した後の初歩的な消化の成果で、もし間違いがあれば、指摘を歓迎します.
学習用コードGithubウェアハウス:shelmingsong/django_rest_framework
参考になる公式サイトのドキュメント:Tutorial 1:Serialization
ブログ更新アドレス