初次就這麼給了你(Django-rest-framework)

庫庫的碼農發表於2017-09-26

Django-Rest-Framework

Django-Rest框架是構建Web API強大而靈活的工具包。

簡單粗暴,直奔主題。

pip install django

pip install djangorestframework

pip install pygments                 #  程式碼顯示高亮

pip安裝好需要的工具包之後,我們就開始建立一個框架。

開啟終端。
cd ~    切換到根目錄下, (那個目錄頁可以,看自己想往哪裡建立)

django-admin.py startproject test_restframework     # 建立工程

建立好之後切換進工程裡邊。

cd test_restframework

工程已經建立好了,需要cd進工程裡邊,關鍵是manage.py在工程裡邊,我們就需要借用manage.py來進行其他的操作了。

給工程新增api

python manage.py startapp test_restapi           #  建立api

建立好之後,接下來,我們需要對django框架進行一些設定了(settings.py)

進入工程目錄(test_restframework)找到settings.py,點開找見(INSTALLD_APPS)這個配置元祖,然後新增

INSTALLD_APPS = (
    ...
    `rest_framework`,
    `test_restframework.apps.SnippetsConfig`,          # 這裡需要注意的就是  ,不新增有可能會出錯

)

配置新增完成之後,接下來我們改建立model了。

目錄:   test_restapi/model.py

from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_stylea

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`,)

model模型已經建好, 我們還需要模型遷移,並同步資料庫。

注意:同步資料庫命令是在 test_restframework下執行

python manage.py makemigrations test_restapi

python manage.py migrate

資料庫已經同步了,我們還需要在Web API 上新增一些序列化和反序列化的例項的方法,例如 json ,我們可以通過宣告序列化器來實現這一點,這些序列化器的工作方式與Django的表單相似,在test_restapi目錄中建立一個serializer.py檔案,新增以下程式碼。

from rest_framework import serializers
from test_restapi.models import Snipper, LANGUAGE_CHOICES, STYLE_CHOICES


class SnippetSerialiazer(zerializers.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):
        return Snippet.object.create(**validated_data)

    def update(self, instance, 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

 serializer類的第一部分定義了被序列化反序列化的欄位,create()和update()方法定義了在呼叫serializer.save()時如何建立或修改完全成熟的例項,

serializer類非常類似於django form類,它包括在不同的欄位上的類似驗證標誌,如required、max_length和default。

欄位標誌還可以控制在某些情況下序列化程式的顯示方式,比如向HTML呈現的情況。

使用序列化器

在使用之前我們需要進入Django-shell。

python manage.py shell

進入shell之後我們需要輸入:

from test_restapi.models import Snippet
from test_restapi.serializers import SnippetSerializer
from rest_framework.renders import JSONRenderer
from rest_framework.parsers import JSONParser


snippet = Snippet(code=`foo = "bar"
`)
snippet.save()

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原生資料型別,為了完成序列化過程, 我們將資料轉化為json。

content = JSONRenderer().render(serializer.data)
content
# `{"id": 2, "title": "", "code": "print \"hello, world\"\n", "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() # <Snippet: Snippet object>

我們還可以序列化querysets而不是模型例項,為此, 我們只需要在序列化器中新增 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

將test_restapi/serializers.py檔案裡的程式碼替換為:

class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = (`id`, `title`, `code`, `linenos`, `language`, `style`)

序列器有一個很好的屬性,可以同過它來列印它的表示,來檢查序列化器例項中所有的欄位,開啟 Django shell

python manage.py shell
from test_restapi.serializers import SnippetSerializer
serializer = SnippetSerializer()
print(repr(serializer))

重要的是要記住ModelSerializer類並沒有做什麼特別神奇的事情,它們只是建立序列化的快捷方式。

使用序列化器編寫常規的django檢視

目錄: test_restapi/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


@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)

最後定義路由,將檢視連線起來。

目錄:  test_restapi/urls.py

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),
]

目錄:  test_restframework/urls.py

from django.conf.urls import url, include

urlpatterns = [
    url(r`^`, include(`test_resrapi.urls`)),
]

安裝httpie,我們可以通過curl來測試api,但是httpie也是一種很友好的測試包。

pip install httpie

最後啟動工程

python manage.py runserver

工程起來之後,開啟瀏覽器,輸入url就可以看到結果了。  ^.^

以上資料來自官網。如有 不明白之處,可以查詢官網示例:  http://www.django-rest-framework.org/tutorial/1-serialization/

 


相關文章