Django休息框架URL过滤器 - 通过过滤方法

时间:2018-01-18 22:50:15

标签: python django django-rest-framework django-filter

我成功使用filter_fields返回单个过滤结果列表。

我想更新到此结果。

有没有办法更新过滤后的单个结果?通过如下的URL模式?

本地主机:8080 / PriceMaster / ISIN = AAA&安培; valuedate = 2018年1月1日

我知道如果我使用URL末尾的主键而不是过滤器我可以更新实例。

我觉得我可能需要使用新的网址制作第二个视图(继承其中一个API视图)?

RetrieveUpdateAPIView,RetrieveDestroyAPIView,RetrieveUpdateDestroyAPIView

有没有办法将它保存在1 ViewSet中?它看起来像什么?

这是我当前的 views.py

class PriceMasterViewSet(ModelViewSet):
    queryset = PriceMaster.objects.filter(vflag=1)
    lookup_field = 'django_id'
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('ISIN', 'ValueDate',)
    model = PriceMaster

当我在邮递员中对URL进行PUT,PATCH或POST时,我收到错误" Method Not Allowed"

由于

编辑1

正如预期的那样,当我添加第二个视图集(继承RetrieveUpdateDestroyAPIView)和一个新URL时,我可以检索已过滤的实例并进行更改。

其他观点

class PriceMasterEditSet(RetrieveUpdateDestroyAPIView):
    def get_object(self):
        queryset = PriceMaster.objects.filter(vflag=1)
        if 'ISIN' in self.request.query_params and 'valuedate' in self.request.query_params:
            filter_kwargs = {'ISIN': self.request.query_params['ISIN'],
                            'valuedate': self.request.query_params['valuedate']}
        else:
            raise Http404('Missing required parameters')

        obj = get_object_or_404(queryset, **filter_kwargs)
        self.check_object_permissions(self.request, obj)

        return obj

添加到模式的附加网址

url(r'^PriceMaster/edit', PriceMasterEditSet.as_view())

我仍然问我可以在1个ViewSet中执行此操作吗?

1 个答案:

答案 0 :(得分:0)

首先,您似乎对RESTful概念感到困惑,您的思维过程和设计似乎更像RPC API模式。 REST的作者有great article about this,他解释了这些差异。

基本上,使用REST API,您应该让HTTP谓词定义您要执行的操作,而在RPC中,您要为每个要执行的操作设置不同的URL,例如:编辑,删除,更新等。这似乎是您正在做的方法。如果您使用Django Rest 框架,我建议您不要这样做,而是遵循RESTful模式。

解决您的具体问题

您的过滤视图是列表视图,而不是详细视图。您可以按查询参数过滤对象列表,并且您的响应是对象列表[{...}, {...}, {...}]。更新对象的PUT请求应针对详细视图而不是列表视图进行。

在您的情况下,列表视图为http://localhost:8080/PriceMaster/,详细视图为http://localhost:8080/PriceMaster/1,其中最后的数字是您要查看的对象的主键。

列表视图接受POST(创建)和GET(阅读),而详细视图接受DELETE,{ {1}}(更新)和PUT(部分更新)。

默认情况下,PATCH将为列表视图和详细视图设置路由。为了让它发挥作用,你无需做任何事情。

相关问题