最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python的Django REST框架中的序列化及請求和返回

 更新時間:2016年04月11日 15:26:58   作者:zhaoyingm  
這篇文章主要介紹了Python的Django REST框架中的序列化及請求和返回,使用Django REST來實現RESTful web service非常方便和強大,需要的朋友可以參考下

序列化Serialization
1. 設置一個新的環(huán)境

在我們開始之前, 我們首先使用virtualenv要創(chuàng)建一個新的虛擬環(huán)境,以使我們的配置和我們的其他項目配置徹底分開。

$mkdir ~/env

$virtualenv ~/env/tutorial

$source ~/env/tutorial/bin/avtivate

現在我們處在一個虛擬的環(huán)境中,開始安裝我們的依賴包

$pip install django

$pip install djangorestframework

$pip install pygments  ////使用這個包,做代碼高亮顯示

需要退出虛擬環(huán)境時,運行deactivate。更多信息,irtualenv document

2. 開始

環(huán)境準備好只好,我們開始創(chuàng)建我們的項目

$ cd ~

$ django-admin.py startproject tutorial

$ cd tutorial

項目創(chuàng)建好后,我們再創(chuàng)建一個簡單的app

$python manage.py startapp snippets

我們使用sqlite3來運行我們的項目tutorial,編輯tutorial/settings.py, 將數據庫的默認引擎engine改為sqlite3, 數據庫的名字NAME改為tmp.db

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': 'tmp.db',
    'USER': '',
    'PASSWORD': '',
    'HOST': '',
    'PORT': '',
  }
}

同時更改settings.py文件中的INSTALLD_APPS,添加我們的APP snippets和rest_framework

INSTALLED_APPS = (
  ...
  'rest_framework',
  'snippets',
)

在tutorial/urls.py中,將snippets app的url包含進來

urlpatterns = patterns('',
  url(r'^', include('snippets.urls')),
)

3. 創(chuàng)建Model
這里我們創(chuàng)建一個簡單的nippets model,目的是用來存儲代碼片段。

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, 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時,記得sync下數據庫

python manage.py syncdb

4. 創(chuàng)建序列化類

我們要使用我們的web api,要做的第一件事就是序列化和反序列化, 以便snippets實例能轉換為可表述的內容,例如json. 我們聲明一個可有效工作的串行器serializer。在snippets目錄下面,該串行器與django 的表單形式很類似。創(chuàng)建一個serializers.py ,并將下面內容拷貝到文件中。

from django.forms import widgets
from rest_framework import serializers
from snippets.models import Snippet

class SnippetSerializer(serializers.Serializer):
  pk = serializers.Field() # Note: `Field` is an untyped read-only field.
  title = serializers.CharField(required=False,
                 max_length=100)
  code = serializers.CharField(widget=widgets.Textarea,
                 max_length=100000)
  linenos = serializers.BooleanField(required=False)
  language = serializers.ChoiceField(choices=models.LANGUAGE_CHOICES,
                    default='python')
  style = serializers.ChoiceField(choices=models.STYLE_CHOICES,
                  default='friendly')

  def restore_object(self, attrs, instance=None):
    """
    Create or update a new snippet instance.
    """
    if instance:
      # Update existing instance
      instance.title = attrs['title']
      instance.code = attrs['code']
      instance.linenos = attrs['linenos']
      instance.language = attrs['language']
      instance.style = attrs['style']
      return instance

    # Create new instance
    return Snippet(**attrs)

該序列化類的前面部分,定義了要序列化和反序列化的類型,restore_object 方法定義了如何通過反序列化數據,生成正確的對象實例。

我們也可以使用ModelSerializer來快速生成,后面我們將節(jié)省如何使用它。
5. 使用 Serializers

在我們使用我們定義的SnippetsSerializers之前,我們先熟悉下Snippets.

 $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='print "hello, world"\n')
snippet.save()


我們現在獲得了一個Snippets的實例,現在我們對他進行以下序列化

serializer = SnippetSerializer(snippet)
serializer.data
# {'pk': 1, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}

這時,我們將該實例轉成了python原生的數據類型。下面我們將該數據轉換成json格式,以完成序列化:

content = JSONRenderer().render(serializer.data)
content
# '{"pk": 1, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'

反序列化也很簡單,首先我們要將一個輸入流(content),轉換成python的原生數據類型

import StringIO

stream = StringIO.StringIO(content)
data = JSONParser().parse(stream)

然后我們將該原生數據類型,轉換成對象實例

serializer = SnippetSerializer(data=data)
serializer.is_valid()
# True
serializer.object
# <Snippet: Snippet object>

注意這些API和django表單的相似處。這些相似點, 在我們講述在view中使用serializers時將更加明顯。
6. 使用 ModelSerializers

SnippetSerializer使用了許多和Snippet中相同的代碼。如果我們能把這部分代碼去掉,看上去將更佳簡潔。

類似與django提供Form類和ModelForm類,Rest Framework也包含了Serializer 類和 ModelSerializer類。

打開snippets/serializers.py ,修改SnippetSerializer類:

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

7. 通過Serializer編寫Django View

讓我們來看一下,如何通過我們創(chuàng)建的serializer類編寫django view。這里我們不使用rest framework的其他特性,僅編寫正常的django view。

我們創(chuàng)建一個HttpResponse 子類,這樣我們可以將我們返回的任何數據轉換成json。

在snippet/views.py中添加以下內容:

from django.http import HttpResponse
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

class JSONResponse(HttpResponse):
  """
  An HttpResponse that renders it's content into JSON.
  """
  def __init__(self, data, **kwargs):
    content = JSONRenderer().render(data)
    kwargs['content_type'] = 'application/json'
    super(JSONResponse, self).__init__(content, **kwargs)

我們API的目的是,可以通過view來列舉全部的Snippet的內容,或者創(chuàng)建一個新的snippet

@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)
    return JSONResponse(serializer.data)

  elif request.method == 'POST':
    data = JSONParser().parse(request)
    serializer = SnippetSerializer(data=data)
    if serializer.is_valid():
      serializer.save()
      return JSONResponse(serializer.data, status=201)
    else:
      return JSONResponse(serializer.errors, status=400)

注意,因為我們要通過client向該view post一個請求,所以我們要將該view 標注為csrf_exempt, 以說明不是一個CSRF事件。
Note that because we want to be able to POST to this view from clients that won't have a CSRF token we need to mark the view as csrf_exempt. This isn't something that you'd normally want to do, and REST framework views actually use more sensible behavior than this, but it'll do for our purposes right now.
我們也需要一個view來操作一個單獨的Snippet,以便能更新/刪除該對象。

@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)
    else:
      return JSONResponse(serializer.errors, status=400)

  elif request.method == 'DELETE':
    snippet.delete()
    return HttpResponse(status=204)


將views.py保存,在Snippets目錄下面創(chuàng)建urls.py,添加以下內容:

urlpatterns = patterns('snippets.views',
  url(r'^snippets/$', 'snippet_list'),
  url(r'^snippets/(?P<pk>[0-9]+)/$', 'snippet_detail'),
)

注意我們有些邊緣事件沒有處理,服務器可能會拋出500異常。
8. 測試

現在我們啟動server來測試我們的Snippet。

在python mange.py shell終端下執(zhí)行(如果前面進入還沒有退出)

 >>quit()

執(zhí)行下面的命令, 運行我們的server:

 python manage.py runserver

Validating models...

0 errors found
Django version 1.4.3, using settings 'tutorial.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

新開一個terminal來測試我們的server

序列化:

url http://127.0.0.1:8000/snippets/

[{"id": 1, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"}]
 url http://127.0.0.1:8000/snippets/1/

{"id": 1, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"}



Request and Response
1. Request Object  ——Request對象

rest framework 引入了一個繼承自HttpRequest的Request對象,該對象提供了對請求的更靈活解析。request對象的核心部分是request.data屬性,類似于request.post, 但在使用WEB API時,request.data更有效。

(1)request.POST  # Only handles form data.  Only works for 'POST' method.
(2)request.DATA  # Handles arbitrary data.  Works any HTTP request with content.
2. Response Object ——Response對象
rest framework引入了一個Response 對象,它繼承自TemplateResponse對象。它獲得未渲染的內容并通過內容協商content negotiation 來決定正確的content type返回給client。

return Response(data)  # Renders to content type as requested by the client.
3. Status Codes
在views當中使用數字化的HTTP狀態(tài)碼,會使你的代碼不宜閱讀,且不容易發(fā)現代碼中的錯誤。rest framework為每個狀態(tài)碼提供了更明確的標識。例如HTTP_400_BAD_REQUEST。相比于使用數字,在整個views中使用這類標識符將更好。
4. 封裝API views

在編寫API views時,REST Framework提供了兩種wrappers:

1). @api_viwe 裝飾器 ——函數級別

2). APIView 類——類級別

這兩種封裝器提供了許多功能,例如,確保在view當中能夠接收到Request實例;往Response中增加內容以便內容協商content negotiation 機制能夠執(zhí)行。

封裝器也提供一些行為,例如在適當的時候返回405 Methord Not Allowed響應;在訪問多類型的輸入request.DATA時,處理任何的ParseError異常。
5. 匯總

我們開始用這些新的組件來寫一些views。

我們不在需要JESONResponse 類(在前一篇中創(chuàng)建),將它刪除。刪除后我們開始稍微重構下我們的view

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer

@api_view(['GET', 'POST'])
def snippet_list(request):
  """
  List all snippets, or create a new snippet.
  """
  if request.method == 'GET':
    snippets = Snippet.objects.all()
    serializer = SnippetSerializer(snippets)
    return Response(serializer.data)

  elif request.method == 'POST':
    serializer = SnippetSerializer(data=request.DATA)
    if serializer.is_valid():
      serializer.save()
      return Response(serializer.data, status=status.HTTP_201_CREATED)
    else:
      return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

上面的代碼是對我們之前代碼的改進。看上去更簡潔,也更類似于django的forms api形式。我們也采用了狀態(tài)碼,使返回值更加明確。
下面是對單個snippet操作的view更新:

@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, pk):
  """
  Retrieve, update or delete a snippet instance.
  """       
  try:
    snippet = Snippet.objects.get(pk=pk)
  except Snippet.DoesNotExist:
    return Response(status=status.HTTP_404_NOT_FOUND)

  if request.method == 'GET':
    serializer = SnippetSerializer(snippet)
    return Response(serializer.data)

  elif request.method == 'PUT':
    serializer = SnippetSerializer(snippet, data=request.DATA)
    if serializer.is_valid():
      serializer.save()
      return Response(serializer.data)
    else:
      return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

  elif request.method == 'DELETE':
    snippet.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

注意,我們并沒有明確的要求requests或者responses給出content type。request.DATA可以處理輸入的json請求,也可以輸入yaml和其他格式。類似的在response返回數據時,REST Framework返回正確的content type給client。

6. 給URLs增加可選的格式后綴

利用在response時不需要指定content type這一事實,我們在API端增加格式的后綴。使用格式后綴,可以明確的指出使用某種格式,意味著我們的API可以處理類似http://example.com/api/items/4.json.的URL。

增加format參數在views中,如:

def snippet_list(request, format=None):
and

def snippet_detail(request, pk, format=None):

現在稍微改動urls.py文件,在現有的URLs中添加一個格式后綴pattterns (format_suffix_patterns):

from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = patterns('snippets.views',
  url(r'^snippets/$', 'snippet_list'),
  url(r'^snippets/(?P<pk>[0-9]+)$', 'snippet_detail'),
)

urlpatterns = format_suffix_patterns(urlpatterns)

這些額外的url patterns并不是必須的。

相關文章

  • 詳解Python中的List

    詳解Python中的List

    這篇文章主要為大家介紹了Python中的List,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • python使用openpyxl庫處理Excel文件詳細教程

    python使用openpyxl庫處理Excel文件詳細教程

    這篇文章主要給大家介紹了關于python使用openpyxl庫處理Excel文件詳細教程的相關資料,openpyxl屬于第三方模塊,在python中用來處理excel文件,可以對excel進行的操作有讀寫、修改、調整樣式及插入圖片等,需要的朋友可以參考下
    2023-11-11
  • 基于Python的關鍵字監(jiān)控及告警

    基于Python的關鍵字監(jiān)控及告警

    這篇文章主要為大家詳細介紹了基于Python的關鍵字監(jiān)控及告警,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • python之鏈表的反轉方式

    python之鏈表的反轉方式

    這篇文章主要介紹了python之鏈表的反轉方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • python pandas模塊進行數據分析

    python pandas模塊進行數據分析

    Python的Pandas模塊是一個強大的數據處理工具,可以用來讀取、處理和分析各種數據,本文主要介紹了python pandas模塊進行數據分析,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 實用自動化運維Python腳本分享

    實用自動化運維Python腳本分享

    今天小編就為大家分享一篇實用自動化運維Python腳本。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • 使用Python的音樂播放器GUI的實現

    使用Python的音樂播放器GUI的實現

    本文主要介紹了使用Python的音樂播放器GUI的實現,可以讓您快速輕松地管理和收聽所有音樂文件,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Python 2種方法求某個范圍內的所有素數(質數)

    Python 2種方法求某個范圍內的所有素數(質數)

    這篇文章主要介紹了Python 2種方法求某個范圍內的所有素數(質數),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • PyQt5 加載圖片和文本文件的實例

    PyQt5 加載圖片和文本文件的實例

    今天小編就為大家分享一篇PyQt5 加載圖片和文本文件的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • python SSH模塊登錄,遠程機執(zhí)行shell命令實例解析

    python SSH模塊登錄,遠程機執(zhí)行shell命令實例解析

    這篇文章主要介紹了python SSH模塊登錄,遠程機執(zhí)行shell命令實例解析,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01

最新評論

夏津县| 都江堰市| 弋阳县| 锡林郭勒盟| 三穗县| 冀州市| 繁峙县| 杭锦旗| 聂拉木县| 图木舒克市| 贵阳市| 阳信县| 大同市| 盐池县| 垫江县| 博罗县| 江源县| 威远县| 丹阳市| 靖远县| 澄城县| 临海市| 合作市| 崇文区| 社旗县| 奉节县| 定边县| 翁牛特旗| 义马市| 济源市| 沈丘县| 资中县| 海口市| 湘阴县| 桓台县| 眉山市| 仁化县| 隆回县| 磐安县| 伊川县| 苏尼特右旗|