Django REST Framework API Guide 03
本节大纲
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_JSON和COMPACT_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的更多相关文章
- Django REST Framework API Guide 01
之前按照REST Framework官方文档提供的简介写了一系列的简单的介绍博客,说白了就是翻译了一下简介,而且翻译的很烂.到真正的生产时,就会发现很鸡肋,连熟悉大概知道rest framework都 ...
- Django REST Framework API Guide 08
1.Filtering 2.Pagination FIltering GenericAPIView的子类筛选queryset的简单方法是重写.get_quueryset()方法. 1.根据当前用户进行 ...
- Django REST Framework API Guide 06
本节大纲 1.Validators 2.Authentication Validators 在REST框架中处理验证的大多数时间,您将仅仅依赖于缺省字段验证,或在序列化器或字段类上编写显式验证方法.但 ...
- Django REST Framework API Guide 04
本节大纲 1.serializers 1.Serializers Serializers允许复杂的数据,像queryset和模型实例转换成源生的Python数据类型.从而可以更简单的被渲染成JSON, ...
- Django REST Framework API Guide 02
本节大纲 1.Generic Views 2.ViewSets 1.Generic Views CBV的主要的一个优点就是极大的允许了对于代码的从用.自然,rest framework取其优势,提供 ...
- Django REST Framework API Guide 07
本节大纲 1.Permissions 2.Throttling Permissions 权限是用来授权或者拒绝用户访问API的不同部分的不同的类的.基础的权限划分 1.IsAuthenticated ...
- Django REST Framework API Guide 05
本节大纲 1.Serializer fields 2.Serializer relations Serializer fields 1.serializer 字段定义在fields.py文件内 2.导 ...
- Django Rest Framework API指南
Django Rest Framework API指南 Django Rest Framework 所有API如下: Request 请求 Response 响应 View 视图 Generic vi ...
- 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 ...
随机推荐
- PMP学习经验总结——ITTO第六版教材
今天小编送的都是干货哦!大家可以收藏一下对学习PMP和项目管理都有很大收获. 4.1 制定项目章程——启动——一次或仅在项目的预定义点开展 概念:编写一份正式批准项目并授权项目经理在项目活动中使用组织 ...
- spring整合redis连接
两种连接方式:(写了一半,未测试) spring xml: <?xml version="1.0" encoding="UTF-8"?> <b ...
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊(分块算法)
传送门 题意: 中文题意,不再赘述. 题解: 下午在补分块算法的相关知识,看到某大神博客推荐的这道题目,就试着做了做: TLE了一下午可还行: 我的思路: 将这 n 个点分成 sqrt(n) 块: i ...
- Linux 单引号和双引号的区别
1.单引号 单引号将其中的内容都作为了字符串来,忽略所有的命令和特殊字符,类似于一个字符串的用法 $echo 'This is a string' This is a string $echo 'ls ...
- Zabbix Web API Get方法整合
#!/usr/bin/python3 import requests,json,re,time,datetime url = 'http://xxx.com/api_jsonrpc.php' ...
- Python编程快速上手-让繁琐工作自动化-第二章习题及其答案
Python编程快速上手-让繁琐工作自动化-第二章习题及其答案 1.布尔数据类型的两个值是什么?如何拼写? 答:True和False,使用大写的T和大写的F,其他字母是小写. 2.3个布尔操作符是什么 ...
- SpringBoot项目部署在同一个tomcat容器报错
在一个Tomcat容器中部署了两个springboot的应用,在启动时发现一直都是第一个启动的项目能启动成功,第二个项目启动报错,错误信息如下: 2018-01-30 15:49:27.810 ERR ...
- Matlab2017A破解版安装详细图文教程(附破解补丁) 64位
摘录网址:http://www.jb51.net/softjc/543170.html MATLAB2017a安装教程: 1.下载并解压本站提供的MATLAB2017a破解版安装包,载入右键解压或者使 ...
- mssql 数据库表行转列,列转行 比较经典
--行列互转 /******************************************************************************************** ...
- java项目反编译获得源码
经常能找到一些 过时的 项目源码,但是还是有研究价值的.但是肯定是不会给你源码的. 下面介绍怎么反编译: 1.在项目中找到classes这个文件夹,这个就是编译过的文件. 2.下载反编译工具JD-GU ...