【问题标题】:Django rest framework URL Filter - Edit/Update Instance returned via filter methodDjango rest 框架 URL 过滤器 - 通过过滤器方法返回的编辑/更新实例
【发布时间】:2018-06-28 03:11:52
【问题描述】:

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

我想更新这个结果。

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

LocalHost:8080/PriceMaster/?ISIN=aaa&valuedate=2018-01-01

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

我觉得我可能需要使用新的 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

当我在 Postman 中对 URL 进行 PUT、PATCH 或 POST 时,我收到错误“方法不允许”

谢谢

编辑 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

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

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

【问题讨论】:

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


    【解决方案1】:

    首先,您似乎对 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(读取),而详细视图接受DELETEPUT(更新)和PATCH(部分更新)。

    ModelViewSet 默认会为列表视图和详细视图设置路由。您无需执行任何操作即可使其正常工作。

    【讨论】:

    • 谢谢,我接受这一点以及您对我对 REST 的困惑的看法。我将阅读概述的文章。我正在处理带有复合列主键的旧版 SQL 数据库,并且正在尝试一些变通方法,因为我真的没有我认为在您的解决方案中提供的“ID”列的奢侈。
    • @GlennSampson 我想说你的django_id 可能是每个对象的Django 主键。无论如何,如果您想接受答案,您必须按我的答案旁边的复选标记。我希望我能提供帮助。
    • 你是对的,我已经实现了 django_id 列进行测试
    猜你喜欢
    • 2014-02-17
    • 2017-10-26
    • 2018-05-17
    • 2012-12-24
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    相关资源
    最近更新 更多