本測試項目例子地址爲:html
tomchristie/rest-framework-tutorialpython
virtualenv env source env/bin/activate
pip install django pip install djangorestframework pip install pygments # We'll be using this for the code highlighting(代碼高亮)
cd ~ django-admin.py startproject tutorial cd tutorial
python manage.py startapp snippets
```INSTALLED_APPS = (git
'rest_framework', 'snippets.apps.SnippetsConfig',
```github
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',)
python manage.py makemigrations snippets python manage.py migrate
咱們須要開始使用Web API的第一件事就是提供一種將代碼片斷實例序列化和反序列化爲表示形式的方法json。咱們能夠經過聲明與Django的表單很是類似的序列化器來實現這一點。在snippets名爲的目錄中建立一個文件serializers.py並添加如下內容。shell
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
序列化器類的第一部分定義了序列化/反序列化的字段。該create()和update()方法定義實例如何徹底成熟的建立或修改時調用serializer.save()數據庫
甲串行類很是相似於一個Django Form類,而且包括關於各個字段相似的驗證標記,如required,max_length和default。django
字段標誌還能夠控制在某些狀況下應該如何顯示序列化程序,例如在呈現爲HTML時。{'base_template': 'textarea.html'}上面的標誌等同於widget=widgets.Textarea在Django Form類上使用。這對於控制如何顯示可瀏覽的API特別有用,正如咱們將在本教程後面看到的。json
咱們實際上也能夠經過使用這個ModelSerializer類節省一些時間,咱們稍後會看到,但如今咱們將保持咱們的序列化器定義清晰。vim
在咱們繼續以前,咱們將熟悉使用咱們的新Serializer類。咱們來看看Django shell。api
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"\n') snippet.save() snippet = Snippet(code='print "hello, world"\n') snippet.save()
serializer = SnippetSerializer(snippet) serializer.data # {'id': 2, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}
content = JSONRenderer().render(serializer.data) content # '{"id": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'
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"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]) serializer.save() # <Snippet: Snippet object>
咱們也能夠序列化查詢集而不是模型實例。爲此,咱們只需many=True在序列化參數中添加一個標誌便可
serializer = SnippetSerializer(Snippet.objects.all(), many=True) serializer.data # [OrderedDict([('id', 1), ('title', u''), ('code', u'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', u''), ('code', u'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]
前面咱們SnippetSerializer類複製Snippet模型中包含的大量信息。若是咱們能夠保持咱們的代碼更加簡潔。
讓咱們看看使用ModelSerializer類重構咱們的序列化程序。snippets/serializers.py再次打開文件,把SnippetSerializer類從新定義,以下
class SnippetSerializer(serializers.ModelSerializer): class Meta: model = Snippet fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
記住ModelSerializer類不要作任何特別的事情是很重要的,它們只是建立序列化類的一個捷徑。
編輯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 ##ddvim @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)
from django.conf.urls import url, include from snippets import views # Additionally, we include login URLs for the browsable API. urlpatterns = [ url(r'^snippets/$',views.snippet_list), url(r'^snippets/(?P<pk>[0-9]+)/$',views.snippet_detail), ]
pip install httpie
http http://127.0.0.1:8000/snippets/ HTTP/1.1 200 OK ... [ { "id": 1, "title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly" }, { "id": 2, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly" } ]
http http://127.0.0.1:8000/snippets/2/ HTTP/1.1 200 OK ... { "id": 2, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly" }