Django REST Framework API Guide 03

本節大綱javascript

  一、Routershtml

  二、Parsersjava

  三、Renderersdjango

Routers

Usagejson

from rest_framework import routers router = routers.SimpleRouter() router.register(r'users', UserViewSet) router.register(r'accounts', AccountViewSet) urlpatterns = router.urls

register的兩個必填參數prefix, viewset, 可選參數base_name,用於建立URL名稱的基礎。若是未設置,將根據視圖集的queryset屬性自動生成basename注意,若是視圖集不包含queryset屬性,那麼在註冊viewset時必須設置base_name。api

以前上一章關於視圖集的截圖裏面其實就已經能夠發現這一點。瀏覽器

樣例:網絡

若是都沒有定義會報錯app

'base_name' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.

 

Using include with routers框架

能夠添加路由以下

router = routers.SimpleRouter() router.register(r'users', UserViewSet) router.register(r'accounts', AccountViewSet) urlpatterns = [ url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), ] urlpatterns += router.urls

另外,可使用Django的include方法

urlpatterns = [ url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), url(r'^', include(router.urls)), ]

也可使用include帶上app的命名空間:

urlpatterns = [ url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), url(r'^api/', include((router.urls, 'app_name'))), ]

還能夠帶上app和實例的命名空間

urlpatterns = [ url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), url(r'^api/', include((router.urls, 'app_name'), namespace='instance_name')), ]

 

Routing for extra actions

經過@action裝飾器來標記額外的操做,這些額外的操做會被包含在生成的url裏面,好比上一章給的change_age等等

class StudentViewSet(ModelViewSet): queryset = PersonResource.objects.filter(job=1) serializer_class = PersonModelSerializer @action(methods=['get', 'put'], detail=True) def change_age(self, request, pk=None): student = self.get_object() student.age += 1 student.save() return Response({ 'status': '%s age changed.' % student.name, 'url': self.reverse_action('change-age', args=[pk]), 'url1': self.reverse_action(self.change_age.url_name, args=[pk]) }) @action(detail=False) def ordering(self, request): student = PersonResource.objects.filter(job=1).order_by('modify_time') page = self.paginate_queryset(student) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(student, many=True) return Response(serializer.data)

若是想要修改客製化的action的url

from myapp.permissions import IsAdminOrIsSelf from rest_framework.decorators import action class UserViewSet(ModelViewSet): ... @action(methods=['post'], detail=True, permission_classes=[IsAdminOrIsSelf], url_path='change-password', url_name='change_password') def set_password(self, request, pk=None): ...

 

API Guide

SimpleRouter

默認ULRs經過SimpleRouter建立,添加trailing_slash參數。這個行爲能夠被修改經過設置trailing_slash參數爲False當初始化router

router = SimpleRouter(trailing_slash=False)

尾隨斜槓在Django中是常規的,但在某些其餘框架(如Rails)中默認不使用。您選擇使用哪一種樣式在很大程度上取決於首選項,儘管一些javascript框架可能但願使用特定的路由樣式。

路由器將匹配包含除斜線和週期字符以外的任何字符的查找值。對於更嚴格(或寬鬆)的查找模式,在VIEW集中設置lookup_value_regex屬性。例如,能夠將查找限制爲有效UUIDs:

class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): lookup_field = 'my_model_id' lookup_value_regex = '[0-9a-f]{32}'

 

DefaultRouter

一樣

router = DefaultRouter(trailing_slash=False)

源文檔這邊是講了關於客製化路由,動態路由參數的內容,不過,從個人生產上沒感受到有這個需求,暫時就不看了,先補個連接,有空補充這一塊的知識點。

http://www.django-rest-framework.org/api-guide/routers/

 

 

二、Parsers

REST framework包含了不少內置的Parser類。容許接受不少種媒體類別請求。它也支持定義你本身的客製化解析。

視圖的合法解析器老是定義爲一個列表類,當request.data能夠訪問的時候,rest framework將檢查即將到來的請求頭的content-type,決定用哪一個解析器來解析request的內容。

Setting the parsers

能夠經過使用DEFAULT_PARSER_CLASSES來進行全局設置。好比,下面的設定僅容許JSON內容,代替默認的JSON或者表單數據

REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', ) }

你也能夠爲一個單獨的視圖或者視圖集設置,使用APIView CBV格式。

from rest_framework.parsers import JSONParser from rest_framework.response import Response from rest_framework.views import APIView class ExampleView(APIView): """ A view that can accept POST requests with JSON content. """ parser_classes = (JSONParser,) def post(self, request, format=None): return Response({'received data': request.data})

或者若是用FBV格式的話

from rest_framework.decorators import api_view from rest_framework.decorators import parser_classes from rest_framework.parsers import JSONParser @api_view(['POST']) @parser_classes((JSONParser,)) def example_view(request, format=None): """ A view that can accept POST requests with JSON content. """
    return Response({'received data': request.data})

API Reference

JSONParser  # 解析成json請求內容;.media_tyoe:application/json
MultiPartParser  # 解析HTML表單內容,request.data返回QueryDict數據,你須要使用FormParser和MultiPartParser,來徹底支持html表單數據;.media_type:application/x-www-form-urlencoded
MultiPartParser  # 同上;.media_type:multipart/form-data
FileUploadParser  # 解析源生的上傳文件內容,request.data屬性將會是一個字典,包含一個單獨的鍵'file'對應上傳文件內容。若是使用文件名url關鍵字參數調用FIleUploadParser使用的視圖,則該參數講用做filename。若是沒有filename url關鍵字參數,客戶端必須設置文件名在請求頭的Content-Disposition裏面。好比:Content-Disposition: attachment; filename=upload.jpg;.media_type:*/*

注意:

a、FileUploadParser是用來給能夠上傳文件做爲源生數據請求的本地客戶端使用。對於基於網絡的上傳,或者具備多部分上傳支持的本地客戶端,你須要使用MultiPartParser代替.

b、因爲這個parser的media_type匹配任何的內容類型,FileUploadParser通常是惟一的parser在API視圖上

c、FileUploadParser遵循Django標準的FILE_UPLOAD_HANDLERS設定和request.upload_handlers屬性.

# views.py
class FileUploadView(views.APIView): parser_classes = (FileUploadParser,) def put(self, request, filename, format=None): file_obj = request.data['file'] # ...
        # do some stuff with uploaded file
        # ...
        return Response(status=204) # urls.py
urlpatterns = [ # ...
    url(r'^upload/(?P<filename>[^/]+)$', FileUploadView.as_view()) ]

 

Third party packages

YAML

$ pip install djangorestframework-yaml
# Django setting
REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': ( 'rest_framework_yaml.parsers.YAMLParser', ), 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework_yaml.renderers.YAMLRenderer', ), }

XML

$ pip install djangorestframework-xml
REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': ( 'rest_framework_xml.parsers.XMLParser', ), 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework_xml.renderers.XMLRenderer', ), }

 

Renderers

setting the renderers

如下設置將使用JSON做爲主媒體類型,還包括自描述API。全局的設定使用DEFAULT_RENDERER_CLASSES參數

REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ) }

能夠單獨對一個視圖或者視圖集設置,使用APIView的CBV格式

from django.contrib.auth.models import User from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView class UserCountView(APIView): """ A view that returns the count of active users in JSON. """ renderer_classes = (JSONRenderer, ) def get(self, request, format=None): user_count = User.objects.filter(active=True).count() content = {'user_count': user_count} return Response(content)

或者在FBV格式下,使用@api_view裝飾器

@api_view(['GET']) @renderer_classes((JSONRenderer,)) def user_count_view(request, format=None): """ A view that returns the count of active users in JSON. """ user_count = User.objects.filter(active=True).count() content = {'user_count': user_count} return Response(content)

API Reference

JSONRenderer

轉成json,使用utf-8編碼。默認是使用unicode字符,渲染響應使用緊湊型的格式,沒有沒必要要的空格

{"unicode black star":"","value":999}

客戶端可能會額外的包含一個indent媒體類型參數,從而讓返回的json數據被縮進。好比Accept: application/json; indent=4

{ "unicode black star": "", "value": 999 }

默承認以選擇UNICODE_JSONCOMPACT_JSON

.media_type: application/json

.format: '.json'

.charset: None

 

TemplateHTMLRenderer

模板渲染傳入Response跟其餘的轉換不同,它不須要被序列化,你只須要包含template_name參數當建立Response實例對象的時候

TemplateHTMLRenderer會建立一個RequestContext,使用response.data做爲內容字典根據,並肯定用於呈現上下文的模板名稱。

模板名稱能夠經過如下幾種方式定義:

一、明確的定義template_name傳入response

二、明肯定義.template_name屬性在類上

三、調用view.get_template_names()方法返回結果

class UserDetail(generics.RetrieveAPIView): """ A view that returns a templated HTML representation of a given user. """ queryset = User.objects.all() renderer_classes = (TemplateHTMLRenderer,) def get(self, request, *args, **kwargs): self.object = self.get_object() return Response({'user': self.object}, template_name='user_detail.html')

你可使用TemplateHTMLRenderer返回常規的使用rest框架的html,或者是從同一個終端的HTML和API響應一塊兒

若是您正在構建使用TemplateHTMLRenderer和其餘渲染類的網站,那麼應該考慮將TemplateHTMLRenderer做爲renderer_classes列表中的第一個類列出,這樣即便對於發送格式不佳的ACCEPT:header的瀏覽器,也會優先考慮它。

 

StaticHTMLRenderer

傳入到response的數據是字符串類型

@api_view(('GET',)) @renderer_classes((StaticHTMLRenderer,)) def simple_html_view(request): data = '<html><body><h1>Hello, world</h1></body></html>'
    return Response(data)

 

Third party packages

YAML

$ pip install djangorestframework-yaml
REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': ( 'rest_framework_yaml.parsers.YAMLParser', ), 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework_yaml.renderers.YAMLRenderer', ), }

XML

$ pip install djangorestframework-xml
REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': ( 'rest_framework_xml.parsers.XMLParser', ), 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework_xml.renderers.XMLRenderer', ), }

JSONP

$ pip install djangorestframework-jsonp
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework_jsonp.renderers.JSONPRenderer', ), }

附上連接,至少目前感受,這邊真的不怎麼用獲得

http://www.django-rest-framework.org/api-guide/renderers/

相關文章
相關標籤/搜索