Django REST框架:非模型序列化器

Zak*_*har 148 django rest django-rest-framework

我是Django REST框架的初学者,需要你的建议.我正在开发一个Web服务.该服务必须为其他服务提供REST接口.我需要实现的REST接口不能直接使用我的模型(我的意思是get,put,post,delete操作).相反,它为其他服务提供了一些计算结果.根据请求,我的服务进行一些计算,然后返回结果(不将结果存储在自己的数据库中).

以下是我对如何实现REST接口的理解.如果我错了,请纠正我.

  1. 创建进行计算的类.将其命名为"CalcClass".CalcClass在其工作中使用模型.
    • 计算所需的参数传递给构造函数.
    • 实现calc操作.它将结果返回为"ResultClass".
  2. 创建ResultClass.
    • 源自对象.
    • 它只包含含有calc结果的属性.
    • calc结果的一部分表示为元组的元组.据我了解,进一步序列化为这些结果实现一个单独的类并将这些对象的列表添加到ResultClass会更好.
  3. 为ResultClass创建序列化程序.
    • 从serializers.Serializer派生.
    • calc结果是只读的,因此主要使用Field类作为字段,而不是专门的类,例如IntegerField.
    • 我不应该在ResultClass和Serializer上都不会使用save()方法,因为我不会存储结果(我只想根据请求返回它们).
    • Impl序列化器用于嵌套结果(记住上面提到的元组元组).
  4. 创建视图以返回计算结果.
    • 来自APIView.
    • 需要get().
    • 在get()中创建CalcClass,其中包含从请求中检索的params,调用其calc(),获取ResultClass,创建Serializer并将ResultClass传递给它,返回Response(serializer.data).
  5. 网址
    • 在我的案例中没有api root.我应该有URL来获得各种计算结果(使用diff params计算).
    • 为api浏览添加调用format_suffix_patterns.

我错过了什么?这种方法一般是否正确?

Gab*_*ira 149

Django-rest-framework即使不将它绑定到模型也能很好地工作.您的方法听起来不错,但我相信您可以修改一些步骤以使一切正常.

例如,rest框架附带了一些内置渲染器.开箱即用它可以将JSON和XML返回给API使用者.您也可以通过安装所需的python模块来启用YAML.Django-rest-framework将输出任何基本对象,如dict,list和tuple,而不需要你做任何额外的工作.

所以基本上你只需要创建接受参数的函数或类,执行所有必需的计算并将其结果返回到REST api视图的元组中.如果JSON和/或XML符合您的需求,django-rest-framework将为您处理序列化.

在这种情况下,您可以跳过步骤2和3,只使用一个类进行计算,一个类用于向API使用者进行演示.

以下是一些片段可能会帮助您:

请注意,我没有测试过这个.它只是作为一个例子,但它应该工作:)

CalcClass:

class CalcClass(object):

    def __init__(self, *args, **kw):
        # Initialize any variables you need from the input you get
        pass

    def do_work(self):
        # Do some calculations here
        # returns a tuple ((1,2,3, ), (4,5,6,))
        result = ((1,2,3, ), (4,5,6,)) # final result
        return result
Run Code Online (Sandbox Code Playgroud)

REST视图:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from MyProject.MyApp import CalcClass


class MyRESTView(APIView):

    def get(self, request, *args, **kw):
        # Process any get params that you may need
        # If you don't need to process get params,
        # you can skip this part
        get_arg1 = request.GET.get('arg1', None)
        get_arg2 = request.GET.get('arg2', None)

        # Any URL parameters get passed in **kw
        myClass = CalcClass(get_arg1, get_arg2, *args, **kw)
        result = myClass.do_work()
        response = Response(result, status=status.HTTP_200_OK)
        return response
Run Code Online (Sandbox Code Playgroud)

你的urls.py:

from MyProject.MyApp.views import MyRESTView
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    # this URL passes resource_id in **kw to MyRESTView
    url(r'^api/v1.0/resource/(?P<resource_id>\d+)[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'),
    url(r'^api/v1.0/resource[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'),
)
Run Code Online (Sandbox Code Playgroud)

当您访问http://example.com/api/v1.0/resource/?format=json时,此代码应输出列表列表.如果使用后缀,则可以替换?format=json.json.您还可以通过添加"Content-type"或添加"Accept"标题来指定要返回的编码.

[
  [
    1, 
    2, 
    3
  ], 
  [
    4, 
    5, 
    6
  ]
]
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助你.

  • 我试图遵循这个建议,但我得到:"不能在没有`.model`或`.queryset`属性的视图上应用DjangoModelPermissions." 我已经尝试了提供的确切示例.它可能是最近版本的django-rest-framework的东西吗? (3认同)
  • 嗨,加百列!谢谢您的回答!我已经按照计划实施了我需要的东西。工作正常!我使用了序列化程序以获得更好的json输出。 (2认同)
  • 非常感谢,它节省了我的一天.它应该是文档的一部分. (2认同)