【问题标题】:Django REST framework: non-model serializerDjango REST 框架:非模型序列化器
【发布时间】:2012-11-16 04:24:06
【问题描述】:

我是 Django REST 框架的初学者,需要您的建议。我正在开发一个网络服务。该服务必须为其他服务提供 REST 接口。我需要实现的 REST 接口不能直接使用我的模型(我的意思是获取、放置、发布、删除操作)。相反,它为其他服务提供了一些计算结果。根据请求,我的服务会进行一些计算并仅返回结果(不将结果存储在自己的数据库中)。

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

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

我错过了什么吗?该方法总体上是否正确?

【问题讨论】:

  • 这种方法是正确的,对我来说实际上看起来比接受的答案更优雅(结果数据封装在可重用的结果类型中)。但归根结底,这主要是个人喜好问题,两种方法都可以。

标签: django rest django-rest-framework


【解决方案1】:

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 使用者展示。

这里有几个sn-ps可以帮到你:

请注意,我没有对此进行测试。这只是一个例子,但它应该可以工作:)

计算类:

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

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

你的 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'),
)

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

[
  [
    1, 
    2, 
    3
  ], 
  [
    4, 
    5, 
    6
  ]
]

希望对你有所帮助。

【讨论】:

  • 嗨,加布里埃尔!谢谢您的回答!我已经按照我的计划实现了我需要的东西。工作正常!我使用序列化程序来获得更好的 json 输出。
  • 我试图遵循这个建议,但我得到:“无法在没有 .model.queryset 属性的视图上应用 DjangoModelPermissions。”。我已经尝试了提供的确切示例。可能是最新版本的 django-rest-framework 的问题吗?
  • 这个例子是前段时间写的。从那以后,我再也没有机会与 Django 合作了。但您可能会在这里找到一些有用的东西:django-rest-framework.org/api-guide/routers
  • 这个例子正是我需要的一个服务,我正在做一些没有非模型序列化程序的操作!
  • 谢谢加布里埃尔。所以总的来说,你会同意使用序列化器更健壮,但需要额外的努力?
猜你喜欢
  • 2016-04-07
  • 2013-03-31
  • 2017-11-15
  • 2014-07-26
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
相关资源
最近更新 更多