使用DRF在RESTful API中实现RPC

时间:2014-10-21 14:15:07

标签: django rest django-rest-framework

我正在使用Django Rest Framework来呈现RESTful API。我有一个路由器/视图集/序列化器为Person资源创建一个端点:

/api/People/<id>/

我想要某种方式触发对此资源的非幂等操作(例如send-email-to)。我不得不重新做很多路由/序列化基础设施的一个想法就是在串行器中添加一个只写的布尔字段:

class PersonSerializer(serializers.ModelSerializer):
   send_email = serializers.BooleanField(write_only=True, required=False)

然后向模型添加只写属性:

class Person(models.Model):
  ...
  def do_send_email(self, value):
    # We also need to check the object is fully constructed here, I think
    if do_send_email:
        ...
  send_email = property(fset=do_send_email)

然后我可以PATCH使用send_email=True的有效负载到达终点。

这是使用REST API完成类似RPC功能的最佳方法吗?这是在DRF中实现这一目标的最佳方法吗?理想情况下,我想解决这个问题,尽可能少地实现(即看看解决方案的代码行数是多少)。 send-email-to并不是我想要处理的唯一行动。

1 个答案:

答案 0 :(得分:5)

您可以使用extra actions drf提供的内容。在你的情况下,我会使用@detail_route。

类似的东西:

@detail_route(methods=['post'])
def send_mail(self, request, pk=None):
    send_mail_to(pk)  # Write here your email function.

您必须在Person视图集中定义此功能,因此,要调用此功能,您必须 / people / {person_id} / send_mail POST 其中 {person_id} 是该人的主要密钥。

作为旁注,由于此功能是从客户端同步调用的,可能需要一段时间才能回答,我建议您使用celery。这将允许您异步调用send_mail_to函数,而不会延迟用户响应。