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

原文地址:https://www.cnblogs.com/wuzdandz/p/9628120.html

时间: 2024-11-09 04:36:46

Django REST Framework API Guide 03的相关文章

Django REST framework API开发

RESTful设计方法 1. 域名 应该尽量将API部署在专用域名之下. https://api.example.com 如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下. https://example.org/api/ 2. 版本(Versioning) 应该将API的版本号放入URL. http://www.example.com/app/1.0/foo http://www.example.com/app/1.1/foo http://www.example.com/app/

API Guide(十四)之Permissions

权限 身份验证或身份识别本身通常不足以获取信息或代码的访问权限.为此,请求访问的实体必须具有授权. - 苹果开发者文档 连同认证和限制,权限决定是否应该授予请求或拒绝访问. 在允许继续执行任何其他代码之前,权限检查始终在视图的开始处运行.权限检查通常将使用在所述认证信息request.user和request.auth属性,以确定是否输入请求应该被允许. 权限用于授予或拒绝将不同类别的用户访问到API的不同部分. 最简单的权限是允许访问任何经过身份验证的用户,并拒绝访问任何未经身份验证的用户.这

利用 Django REST framework 编写 RESTful API

利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framework 真乃一大神器,可以轻易的甚至自动化的搞定很多事情,比如: 自动生成符合 RESTful 规范的 API 支持 OPTION.HEAD.POST.GET.PATCH.PUT.DELETE 根据 Content-Type 来动态的返回数据类型(如 text.json) 生成 browserable

Django REST framework 之 API认证

RESTful API 认证 和 Web 应用不同,RESTful APIs 通常是无状态的, 也就意味着不应使用 sessions 或 cookies, 因此每个请求应附带某种授权凭证,因为用户授权状态可能没通过 sessions 或 cookies 维护, 常用的做法是每个请求都发送一个秘密的 access token 来认证用户, 由于 access token 可以唯一识别和认证用户, API 请求应通过 HTTPS 来防止 man-in-the-middle(MitM)中间人攻击. 通

django rest framework 入门

django rest framework 入门1-序列化 Serialization 分类: Python 2013-01-22 22:24 11528人阅读 评论(0) 收藏 举报 djangopythonrest framework ************************************ 广告时间: 海淘导航网站推荐:海淘库:http://www.haitaocool.com/ 需要的请收藏哦 ************************************ 1.

API Guide(四)之Generic views

通用的视图 Django's generic views... were developed as a shortcut for common usage patterns... 它们采取一些常见的习语和模式,在视图开发中创建并抽象,以便可以快速编写数据的常见视图,而无需重复. - Django文档 CBV的主要优点之一是 the way they allow you to compose bits of reusable behavior. REST framework takes advan

Django rest framework 使用自定义认证方式

Django rest framework 使用自定义认证方式 Django使用自定义认证方式 介绍了 "Django使用自定义认证方式",这一篇说说怎样在前一篇的基础上提供rest api. 修改settings.py中INSTALLED_APPS,添加 'login' app. 给login app增加serializers.py文件 #coding:utf-8 from django.contrib.auth.models import User from rest_framew

Django REST framework 的TokenAuth认证及外键Serializer基本实现

一,Models.py中,ForeignKey记得要有related_name属性,已实现关联对象反向引用. app_name = models.ForeignKey("cmdb.App",related_name='deploy_app', verbose_name="App") 二,Settings.py文件中,加入对Django REST framework的基本设置. REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSE

Python【第二十四课】Django rest framework

本节内容 Django rest framework 安装 Django rest framwwork 环境配置 简单举例说明 Django中使用 rest framework 1.1 安装 Django rest framework 建立新的环境 virtualenv env source env/bin/activate 安装 djangorestframework 模块 pip install django pip install djangorestframework pip insta