如何使用Tastypie来包装内部函数

时间:2012-10-26 21:42:20

标签: django api rest tastypie

我有一个Django Web应用程序,它允许用户通过HTTP从远程服务器上执行stop / start / install_pkg。 Django Web应用程序已经实现了start / stop / install_pkg函数,它们基本上创建了相应的URL并使用params调用HTTP url。

我的目标是在用户执行REST调用时使用相同的内部函数,如下所示:

1. https://api/v1/server/<server_name>/start/?api_key=<api_key>&params=<params>
2. https://api/v1/server/<server_name>/stop/?api_key=<api_key>&params=<params>
3. https://api/v1/server/<server_name>/install_pkg/?api_key=<api_key>&params=<params>

将JSON响应返回给包含远程服务器响应对象的调用者。

到目前为止,我已经使用Tastypie库来通过REST公开对Django Web应用程序的模型数据的只读访问。

Non ORM resource上的Tastypie教程展示了如何通过覆盖Tastypie的9种方法来与非ORM资源进行交互。但鉴于我的知识和理解有限,我不清楚如何在我的案例中使用Tastypie。我在这里错过了什么吗?

已编辑:(2012年10月29日)

进一步澄清 - Django Web应用程序为每个远程服务器提供了ORM条目,但此信息是关于特定远程服务器的静态信息,如(name,ip,domain,...),因为它是在当时创建的注册远程服务器到Django Web应用程序。

从Django Web应用程序到远程服务器的Web服务调用获取远程服务器的最新状态,如(app_state,pkg_installed_list,...),并且此数据不会存储在我的Djnago Web应用程序中的任何位置。它在UI中呈现。

因此,关于远程服务器的Django Web应用程序的GET实际上返回静态信息。

谢谢,

1 个答案:

答案 0 :(得分:8)

一种方法是仅跟踪服务器资源,并将start / stop / install_pkg实现为自定义端点。

您将在Tastypie下实现服务器资源,以使用常规的基于ORM的资源为每个服务器提供端点。它实现了资源上的标准REST操作,GET读取服务器信息,如果你说你有管理员用户需要添加另一台服务器来管理服务,PUT / PATCH来更新现有服务器,那么POST就可以创建新服务器。

然后,您将扩展ServerResource以包含其他端点:

  1. 使用prepend_urls定义3个自定义端点(start,stop,install_pkg)
  2. 在ServerResource下的函数中实现每个端点,注意考虑安全性,限制操作(你想要在它们上调用GET或POST吗?)

  3. 另一种方法是将ServiceResource创建为非ORM资源,该资源与服务器资源存在多对多的关系。这是更棘手但可以说更清洁的设计。

    您的ServiceResource将具有2个自定义端点,就像上一个场景(开始/停止)一样,但要在服务器上安装服务,您需要将PUT / PATCH发送到要与该服务关联的ServerResource。

    有关更具体的答案,请说明更具体的问题。


    有关如何继续的详细信息,请参阅Tastypie食谱:

    search example使用您想要在0.9.11中使用的override_urls,并且与0.9.12中的prepend_urls具有类似的行为,但尚未发布。根据您的版本,您需要创建3个自定义端点:

     def override_urls(self):
            return [
                url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/%start%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('start'), name="api_start"),
                url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/%stop%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('stop'), name="api_stop"),
                url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/%install_pkg%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('install_pkg'), name="api_install_pkg"),
            ]
    

    然后,您需要定义类似于ServerResource上的搜索示例的3个处理程序。我将为您提供启动功能的起点。这是同步操作的示例。如果你想要它是异步的,你将需要更多,但它是一个起点。

    from tastypie.http import Http
    
    def start(self, request, **kwargs):
        self.method_check(request, allowed=['post'])
        self.is_authenticated(request)
        self.throttle_check(request)
    
        try:
            output = function_that_starts_server(kwargs['pk'])
        except FailedException as failure:
            return self.create_response(request, { 'status' : 'failure', 'reason' : failure }, Http
    
        self.log_throttled_access(request)
        return self.create_response(request, { 'status' : 'success', 'log' : output })