成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Django REST framework 中文教程1:序列化

zeyu / 1968人閱讀

摘要:我們可以通過聲明與表單非常相似的序列化器來做到這一點(diǎn)。具有的一個(gè)不錯(cuò)的屬性是可以通過打印其表示來檢查序列化器實(shí)例中的所有字段。

建議直接去http://www.chenxm.cc/post/289... 該網(wǎng)址閱讀,本文內(nèi)容之后于該網(wǎng)頁

建立環(huán)境

在我們做任何事情之前,我們將使用virtualenv創(chuàng)建一個(gè)新的虛擬環(huán)境。這將確保我們的包配置與我們正在開展的任何其他項(xiàng)目保持良好的隔離。

virtualenv
envsource env/bin/activate

現(xiàn)在我們?cè)谝粋€(gè)virtualenv環(huán)境中,我們可以安裝我們的包的要求。

pip install django
pip install djangorestframework
pip install pygments  # 我們將使用這個(gè)讓代碼突出顯示

注意:要隨時(shí)退出virtualenv環(huán)境,只需鍵入deactivate。有關(guān)更多信息,請(qǐng)參閱virtualenv文檔。

入門

好的,我們準(zhǔn)備好獲得編碼。要開始,我們來創(chuàng)建一個(gè)新的項(xiàng)目來處理。

cd ~
django-admin.py startproject tutorial
cd tutorial
一旦完成,我們可以創(chuàng)建一個(gè)我們將用來創(chuàng)建一個(gè)簡(jiǎn)單的Web API的應(yīng)用程序。

python manage.py startapp snippets
我們需要添加我們的新snippets應(yīng)用和rest_framework應(yīng)用INSTALLED_APPS。我們來編輯tutorial/settings.py文件:

INSTALLED_APPS = (

...
"rest_framework",
"snippets.apps.SnippetsConfig",

)
請(qǐng)注意,如果你使用的Django <1.9,則需要更換snippets.apps.SnippetsConfig有snippets。

好的,我們準(zhǔn)備好了。

創(chuàng)建一個(gè)可以使用的模型

為了本教程的目的,我們將首先創(chuàng)建一個(gè)Snippet用于存儲(chǔ)代碼片段的簡(jiǎn)單模型。繼續(xù)編輯snippets/models.py文件。注意:良好的編程實(shí)踐包括評(píng)論。雖然您將在本教程代碼的存儲(chǔ)庫版本中找到它們,但我們?cè)诖撕雎粤怂鼈?,專注于代碼本身。

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

我們還需要為我們的代碼段模型創(chuàng)建初始遷移,并首次同步數(shù)據(jù)庫。

python manage.py makemigrations snippets
python manage.py migrate

創(chuàng)建一個(gè)Serializer類

我們需要開始使用Web API的第一件事是提供一種將代碼段實(shí)例序列化和反序列化為表示形式的方式j(luò)son。我們可以通過聲明與Django表單非常相似的序列化器來做到這一點(diǎn)。在snippets命名的目錄中創(chuàng)建一個(gè)文件,serializers.py并添加以下內(nèi)容。

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

使用Serializer

在我們進(jìn)一步了解之前,我們將熟悉使用我們的新的Serializer類。讓我們進(jìn)入Django shell。

python manage.py shell

現(xiàn)在,我們將以下幾個(gè)方法導(dǎo)入進(jìn)去后,可以創(chuàng)建一些代碼片段來測(cè)試以下。

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

# 創(chuàng)建數(shù)據(jù)
snippet = Snippet(code="foo = "bar"
")
snippet.save()

snippet = Snippet(code="print "hello, world"
")
snippet.save()

我們現(xiàn)在有幾個(gè)片段實(shí)例可以嘗試。我們來看看序列化這些實(shí)例之一。

###
 該代碼是把剛剛保存的數(shù)據(jù)snippet對(duì)象,經(jīng)過序列化保存成一個(gè)字典
     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"}

此時(shí),我們將模型實(shí)例轉(zhuǎn)換為Python的數(shù)據(jù)類型。要完成序列化過程需要我們將數(shù)據(jù)渲染成json。

# 將字典轉(zhuǎn)換成json格式
content = JSONRenderer().render(serializer.data)
content
# "{"id": 2, "title": "", "code": "print "hello, world"
", "linenos": false, "language": "python", "style": "friendly"}"
反序列化是類似的。首先我們將一個(gè)流解析成Python支持?jǐn)?shù)據(jù)類型。

# 將json轉(zhuǎn)換成字典格式
from django.utils.six import BytesIO

stream = BytesIO(content)
data = JSONParser().parse(stream)
然后我們將這些本機(jī)數(shù)據(jù)類型恢復(fù)到完全填充的對(duì)象實(shí)例中

serializer = SnippetSerializer(data=data)
serializer.is_valid()    # 驗(yàn)證數(shù)據(jù)是否符合要求
# True
serializer.validated_data    # 驗(yàn)證后的數(shù)據(jù)
# OrderedDict([("title", ""), ("code", "print "hello, world"
"), ("linenos", False), ("language", "python"), ("style", "friendly")])
serializer.save()    # 保存數(shù)據(jù)
# 

請(qǐng)注意API與表單的使用情況。當(dāng)我們開始編寫使用我們的序列化程序的視圖時(shí),相似性將變得更加明顯。

我們也可以序列化查詢集而不是模型實(shí)例。為此,我們只many=True需要為serializer參數(shù)添加一個(gè)標(biāo)志。

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類復(fù)制Snippet模型中大量信息。如果我們可以保持我們的代碼更簡(jiǎn)潔,那就更好。

與Django提供的Form類和ModelForm類一樣,REST框架包括Serializer類和ModelSerializer類。

我們來使用ModelSerializer該類重構(gòu)我們的serializer 。再次打開該文件snippets/serializers.py,并用SnippetSerializer以下代碼替換該類。

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

serializer具有的一個(gè)不錯(cuò)的屬性是可以通過打印其表示來檢查序列化器實(shí)例中的所有字段。打開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類不會(huì)做任何特別神奇的事情,它們只是創(chuàng)建序列化器類的快捷方式:

一組自動(dòng)確定的字段。
簡(jiǎn)單的默認(rèn)實(shí)現(xiàn)create()和update()方法。
使用我們的Serializer編寫正常的Django視圖

我們來看看我們?nèi)绾问褂梦覀兊男碌腟erializer類編寫一些API視圖。目前我們不會(huì)使用任何REST框架的其他功能,我們只需將視圖編寫為常規(guī)的Django視圖。

編輯snippets/views.py文件,并添加以下內(nèi)容。

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本來是一個(gè)視圖函數(shù),支持監(jiān)聽所有已有的代碼或者新建的代碼片段

@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 數(shù)據(jù)創(chuàng)建成功后所有數(shù)據(jù)
            return JsonResponse(serializer.data, status=201)
        # serializer.errors 錯(cuò)誤信息
        return JsonResponse(serializer.errors, status=400)

請(qǐng)注意,因?yàn)槲覀兿M軌驈牟痪哂蠧SRF令牌的客戶端對(duì)此視圖進(jìn)行POST,因此我們需要將視圖標(biāo)記為csrf_exempt。這不是你通常想要做的事情,REST框架視圖實(shí)際上比這更有明確的行為,但它現(xiàn)在將為我們的目的而做。

我們還需要一個(gè)與單個(gè)代碼片段對(duì)應(yīng)的視圖,并可用于檢索,更新或刪除該片段

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

最后我們需要把這些觀點(diǎn)連接起來。創(chuàng)建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文件中連接根urlconf ,以包含我們的片段應(yīng)用程序的URL。

from django.conf.urls import url, include

urlpatterns = [
    url(r"^", include("snippets.urls")),
]

值得注意的是,我們目前還沒有正確處理好幾個(gè)邊緣案例。如果我們發(fā)送格式錯(cuò)誤json,或者如果使用視圖不處理的方法發(fā)出請(qǐng)求,不過,按照現(xiàn)在這樣做,那么我們最終會(huì)出現(xiàn)500“服務(wù)器錯(cuò)誤”響應(yīng)。

測(cè)試我們?cè)赪eb API上的第一次嘗試

現(xiàn)在我們可以啟動(dòng)一個(gè)服務(wù)我們的代碼片段的示例服務(wù)器。

退出shell...

quit()
并啟動(dòng)Django的開發(fā)服務(wù)器。

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.

在另一個(gè)終端窗口中,我們可以測(cè)試服務(wù)器。

我們可以使用curl或httpie來測(cè)試我們的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。

我們現(xiàn)在在哪

我們到目前為止還行,我們有一個(gè)類似于Django的Forms API和一些常規(guī)Django視圖的序列化API。

我們的API視圖目前沒有特別的特別之處,除了提供json響應(yīng)外,還有一些錯(cuò)誤處理我們?nèi)匀幌胍謇淼倪吘壡闆r,但它是一個(gè)運(yùn)行良好的Web API。

我們將在本教程的第2部分中看到我們?nèi)绾伍_始改進(jìn)事情。
Django REST FrameWork中文文檔目錄:

Django REST FrameWork 中文教程1:序列化

Django REST FrameWork 中文教程2:請(qǐng)求和響應(yīng)

Django REST FrameWork 中文教程3:基于類的視圖

Django REST FrameWork 中文教程4:驗(yàn)證和權(quán)限

Django REST FrameWork 中文教程5:關(guān)系和超鏈接API

Django REST FrameWork 中文教程6: ViewSets&Routers

Django REST FrameWork 中文教程7:模式和客戶端庫

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/44455.html

相關(guān)文章

  • Django REST FrameWork中文教程5:關(guān)系和超鏈接API

    摘要:目前我們的中的關(guān)系通過使用主鍵來表示。在本教程的這一部分中,我們將改進(jìn)的內(nèi)聚力和可發(fā)現(xiàn)性,而不是使用超鏈接來進(jìn)行關(guān)系。將相關(guān)實(shí)體嵌套在父表示內(nèi)。 目前我們的API中的關(guān)系通過使用主鍵來表示。在本教程的這一部分中,我們將改進(jìn)API的內(nèi)聚力和可發(fā)現(xiàn)性,而不是使用超鏈接來進(jìn)行關(guān)系。 為我們的API的根創(chuàng)建一個(gè)端點(diǎn)現(xiàn)在我們有snippets和users的端點(diǎn),但是我們的API沒有一個(gè)入口點(diǎn)。要...

    XiNGRZ 評(píng)論0 收藏0
  • Django REST FrameWork中文教程5:關(guān)系和超鏈接API

    摘要:目前我們的中的關(guān)系通過使用主鍵來表示。在本教程的這一部分中,我們將改進(jìn)的內(nèi)聚力和可發(fā)現(xiàn)性,而不是使用超鏈接來進(jìn)行關(guān)系。將相關(guān)實(shí)體嵌套在父表示內(nèi)。 目前我們的API中的關(guān)系通過使用主鍵來表示。在本教程的這一部分中,我們將改進(jìn)API的內(nèi)聚力和可發(fā)現(xiàn)性,而不是使用超鏈接來進(jìn)行關(guān)系。 為我們的API的根創(chuàng)建一個(gè)端點(diǎn)現(xiàn)在我們有snippets和users的端點(diǎn),但是我們的API沒有一個(gè)入口點(diǎn)。要...

    hsluoyz 評(píng)論0 收藏0
  • Django REST FrameWork中文教程5:關(guān)系和超鏈接API

    摘要:目前我們的中的關(guān)系通過使用主鍵來表示。在本教程的這一部分中,我們將改進(jìn)的內(nèi)聚力和可發(fā)現(xiàn)性,而不是使用超鏈接來進(jìn)行關(guān)系。將相關(guān)實(shí)體嵌套在父表示內(nèi)。 目前我們的API中的關(guān)系通過使用主鍵來表示。在本教程的這一部分中,我們將改進(jìn)API的內(nèi)聚力和可發(fā)現(xiàn)性,而不是使用超鏈接來進(jìn)行關(guān)系。 為我們的API的根創(chuàng)建一個(gè)端點(diǎn)現(xiàn)在我們有snippets和users的端點(diǎn),但是我們的API沒有一個(gè)入口點(diǎn)。要...

    waruqi 評(píng)論0 收藏0
  • Django REST FrameWork中文教程3:基于類的視圖

    摘要:看起來不錯(cuò)再次,它現(xiàn)在仍然非常類似于基于功能的視圖。我們還需要重構(gòu)一下我們使用基于類的視圖。中文文檔目錄中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫 我們也可以使用基于類的視圖編寫我們的API視圖,而不是基于函數(shù)的視圖。我們將看到這是一個(gè)強(qiáng)大的模式,允許我們重用常用功能,并幫助我們保持代碼DRY。 使用基于類的...

    UnixAgain 評(píng)論0 收藏0
  • Django REST FrameWork中文教程3:基于類的視圖

    摘要:看起來不錯(cuò)再次,它現(xiàn)在仍然非常類似于基于功能的視圖。我們還需要重構(gòu)一下我們使用基于類的視圖。中文文檔目錄中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫 我們也可以使用基于類的視圖編寫我們的API視圖,而不是基于函數(shù)的視圖。我們將看到這是一個(gè)強(qiáng)大的模式,允許我們重用常用功能,并幫助我們保持代碼DRY。 使用基于類的...

    shiguibiao 評(píng)論0 收藏0
  • Django REST FrameWork中文教程3:基于類的視圖

    摘要:看起來不錯(cuò)再次,它現(xiàn)在仍然非常類似于基于功能的視圖。我們還需要重構(gòu)一下我們使用基于類的視圖。中文文檔目錄中文教程序列化中文教程請(qǐng)求和響應(yīng)中文教程基于類的視圖中文教程驗(yàn)證和權(quán)限中文教程關(guān)系和超鏈接中文教程中文教程模式和客戶端庫 我們也可以使用基于類的視圖編寫我們的API視圖,而不是基于函數(shù)的視圖。我們將看到這是一個(gè)強(qiáng)大的模式,允許我們重用常用功能,并幫助我們保持代碼DRY。 使用基于類的...

    canopus4u 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<