178

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

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

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

我错过了什么?这种方法总体上是正确的吗?

4

1 回答 1

174

Django-rest-framework works well even without tying it to a model. Your approach sounds ok, but I believe you can trim some of the steps to get everything working.

For example, rest framework comes with a few built-in renderers. Out of the box it can return JSON and XML to the API consumer. You can also enable YAML by just installing the required python module. Django-rest-framework will output any basic object like dict, list and tuple without any extra work on your part.

So basically you only have to create the function or class that takes in arguments, does all of the required calculations and returns its results in a tuple to the REST api view. If JSON and/or XML fits your needs, django-rest-framework will take care of the serialization for you.

You can skip steps 2 and 3 in this case, and just use one class for calculations and one for presentation to the API consumer.

Here are a few snippets may help you out:

Please note that I have not tested this. It's only meant as an example, but it should work :)

The 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

The REST view:

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

Your 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'),
)

This code should output a list of lists when you access http://example.com/api/v1.0/resource/?format=json. If using a suffix, you can substitute ?format=json with .json. You may also specify the encoding you wish to get back by adding "Content-type" or "Accept" to the headers.

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

Hope this helps you out.

于 2012-11-29T11:05:25.417 回答