本节大纲

  1、Routers

  2、Parsers

  3、Renderers

Routers

Usage

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。

之前上一章关于视图集的截图里面其实就已经可以发现这一点。

样例:

如果都没有定义会报错

'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/

2、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作为内容字典根据,并确定用于呈现上下文的模板名称。

模板名称可以通过以下几种方式定义:

1、明确的定义template_name传入response

2、明确定义.template_name属性在类上

3、调用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/

Django REST Framework API Guide 03的更多相关文章

  1. Django REST Framework API Guide 01

    之前按照REST Framework官方文档提供的简介写了一系列的简单的介绍博客,说白了就是翻译了一下简介,而且翻译的很烂.到真正的生产时,就会发现很鸡肋,连熟悉大概知道rest framework都 ...

  2. Django REST Framework API Guide 08

    1.Filtering 2.Pagination FIltering GenericAPIView的子类筛选queryset的简单方法是重写.get_quueryset()方法. 1.根据当前用户进行 ...

  3. Django REST Framework API Guide 06

    本节大纲 1.Validators 2.Authentication Validators 在REST框架中处理验证的大多数时间,您将仅仅依赖于缺省字段验证,或在序列化器或字段类上编写显式验证方法.但 ...

  4. Django REST Framework API Guide 04

    本节大纲 1.serializers 1.Serializers Serializers允许复杂的数据,像queryset和模型实例转换成源生的Python数据类型.从而可以更简单的被渲染成JSON, ...

  5. Django REST Framework API Guide 02

    本节大纲 1.Generic Views 2.ViewSets  1.Generic Views CBV的主要的一个优点就是极大的允许了对于代码的从用.自然,rest framework取其优势,提供 ...

  6. Django REST Framework API Guide 07

    本节大纲 1.Permissions 2.Throttling Permissions 权限是用来授权或者拒绝用户访问API的不同部分的不同的类的.基础的权限划分 1.IsAuthenticated ...

  7. Django REST Framework API Guide 05

    本节大纲 1.Serializer fields 2.Serializer relations Serializer fields 1.serializer 字段定义在fields.py文件内 2.导 ...

  8. Django Rest Framework API指南

    Django Rest Framework API指南 Django Rest Framework 所有API如下: Request 请求 Response 响应 View 视图 Generic vi ...

  9. tastypie Django REST framework API [Hello JSON]

    tastypie is a good thing. Haven't test it thoroughly. Gonna need some provement. Now I will introduc ...

随机推荐

  1. ubuntu下 pthread_mutex_init man中查不到

    问题: 如题所述,包括pthread_mutex_init 和 pthread_mutex_lock 这些函数都找不到 解决办法: 安装manpages:manpages-posix-dev Mint ...

  2. mac host文件配置

    Shift+Command+G 三个组合按键,并输入 Hosts 文件的所在路径:/etc/hosts /private/etc/hosts

  3. (数论 最大公约数 最小公倍数) codeVs 1012 最大公约数和最小公倍数问题

    题目描述 Description 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件:  1.P,Q是正整 ...

  4. awk统计文件大小

    在Linux系统中,经常会遇到某个目录下文件很多,要统计这些文件的空间大小.可以采用awk来实现.如下是实现这个功能的例子. vim sum.sh #!/bin/bash# sum.shcd //ba ...

  5. Hbase 1.3.0 Rsgroup

    HBase RSGroup Git环境window环境下,警用crlf自动转换git config --global core.autocrlf false protobuf环境yum install ...

  6. oracle数据泵导入导出命令

    1.在PL/SQL的界面,找到Directories文件夹,找到目录文件的路径 2.通过SSH进入服务器 找到相应的路径 cd /u01/oracle/dpdir 输入指令 df -h   查看资源使 ...

  7. JavaEE之JDBC编程[详解]

    1.数据库简介 数据库(DB,Data Base ) 数据库管理系统(DBMS,Data Base Management System) 关系型数据库(RDB) 关系型数据库管理系统(RDBMS) S ...

  8. 设计模式---领域规则模式之解析器模式(Interpreter)

    前提:领域规则模式 在特定领域内,某些变化虽然频繁,但可以抽象为某种规则.这时候,结合特定领域,将问题抽象为语法规则,从而给出该领域下的一般性解决方案. 典型模式 解析器模式:Interpreter ...

  9. ant design环境搭建过程中遇到的问题--Windows-dva-cli

    基础的此处略去,nodejs和npm是前提. 1.官网介绍的是脚手架工具是antd-init,但是又建议真实项目中用dva-cli,所以博主就直接装的是dva-cli,这里主要是简单介绍下博主在Win ...

  10. Python assert作用

    使用assert断言是学习python一个非常好的习惯,python assert 断言句语格式及用法很简单.在没完善一个程序之前, 我们不知道程序在哪里会出错.与其让它在运行最后崩溃,不如在出现错误 ...