本节大纲

  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. (五)Oracle 的 oracle 表查询

    http://www.hechaku.com/Oracle/oracle_tables_chack.html 通过scott用户下的表来演示如何使用select语句,接下来对emp.dept.salg ...

  2. 扩展方法、委托和Lambda

    举例演化Lambda string[] names ={"Burke", "Connor", "Frank", "Everett& ...

  3. Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践

    转: Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践 阿里加多 0.1 2018.03.23 17:19* 字数 492 阅读 2613评论 2喜欢 1 一.前 ...

  4. 你真的知道什么是【共享Session】,什么是【单点登录】吗?

    一直有人问,为什么我实现的共享session不能单点登录,今天我也抽时间准备好好说一下. 我要喷(别喷我) 首先,网上水货文章很多,CSDN居多.CSDN转载率很高,也就是说同相同文章有很多,换汤不换 ...

  5. [USACO13FEB] Tractor

    题目链接 大家的 Blog 里面都是做过的题目,只有我的里面什么都没有 那我也开始写一点吧 刷着刷着 DP 不知怎的就出来一道这个题……用时 2 hours 后怒而删两个文件重构…… 然后过了……过了 ...

  6. BZOJ2815 拓扑排序 + LCA

    https://www.lydsy.com/JudgeOnline/problem.php?id=2815 作为一个DAG图,结点之间又有这么明显的等级之分,很容易想到的是拓扑排序. 但是不管是正向的 ...

  7. JDBC-HikariCP

    一.依赖 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...

  8. 关于js事件执行顺序

    关于js事件执行顺序小技巧 js事件执行顺序是js中一个老生常谈的一个话题, 聊这个话题之前我们先谈谈怎么给页面元素绑定我们需要的事件 1.给页面元素绑定事件 a)直接在元素上面加上需要绑定的事件,如 ...

  9. PHP7 学习笔记(十二)Stream 函数详解

    官方:http://php.net/manual/zh/ref.stream.php Stream_*系列函数 PHP中对流的描述如下:每一种流都实现了一个包装器(wrapper),包装器包含一些额外 ...

  10. SpringBoot常用注解使用

    1.RequestBody和ResponseBody注解 @RequestMapping(“url”),这里的 url写的是请求路径的一部分,一般作用在 Controller的方法上,作为请求的映射地 ...