Django-filter: 所有 DRF 视图操作在技术上都允许过滤字段。 这与 CoreAPI 架构相混淆。

创建于 2018-05-16  ·  3评论  ·  资料来源: carltongibson/django-filter

在启用 DRF 和DjangoFilterBackend的情况下使用 CoreAPI 时,客户端也会尝试将创建、更新或部分更新操作的所有字段映射到查询参数。 这破坏了客户使用这些方法的能力。

例子

如果我们有一个请求尝试创建具有名称的书籍,并且名称也是我们模型上的可过滤字段:

# book views
class BookViewSet():
    filter_fields = ('name',)
   # ...
// schema
client.action('book', 'create', { 'name': 'My Awesome Book' });

这将在 URL 参数和请求正文中创建一个具有名称的请求。 这不是预期的行为。

POST /api/book?name=My%20Awesome%20Book

name=My Awesome Book

建议的解决方案

我们已经在我们的代码中解决了这个问题,而是使用以下代码将我们的 DRF 过滤器后端指向自定义覆盖:

class OnlyFilterOnReadDjangoFilterBackend(DjangoFilterBackend):
    """ A filter backend that only allows for filtering by properties on
    actions deemed as safe. This means that create, update, and partial_update
    actions will not provide filter options.
    """
    SAFE_ACTIONS = ('list', 'retrieve')

    def get_schema_fields(self, view):
        if view.action in self.SAFE_ACTIONS:
            return super().get_schema_fields(view)
        return []

最有用的评论

嗨@Sonictherocketman。 感谢您的报告。

我的第一个想法是,这是客户端 API 的一个错误——在构造请求时,它没有适当地区分查询字符串参数和请求正文。

通常,仅禁用对非安全操作的过滤是不正确的。 在建立将对其进行更新的基本查询集时发生过滤。

我暂时将其打开,只是为了考虑一下。

所有3条评论

嗨@Sonictherocketman。 感谢您的报告。

我的第一个想法是,这是客户端 API 的一个错误——在构造请求时,它没有适当地区分查询字符串参数和请求正文。

通常,仅禁用对非安全操作的过滤是不正确的。 在建立将对其进行更新的基本查询集时发生过滤。

我暂时将其打开,只是为了考虑一下。

我也有点认为这是一个客户端问题,但我想得越多,我觉得这些操作对写入查询(尤其是写入特定资源)并没有任何意义,而且 imo 架构不应该如果不应该使用这些字段。

感谢您的快速回复,我对您对此的想法非常感兴趣。

或多或少,我认为我们在这里受到我们对_automagic_代码生成超过技术(在当前状态下)的渴望的限制。

对于我们想要的模式(任何可用格式),我们(还)不能做很多事情——例如,对于 CoreAPI,我们还不能将参数组合在一起以显示日期范围过滤器他们是相关的。 (我们可以通过手工编写模式做更多的事情,但当然没有人愿意这样做。)

但它会发展,工具也会随着它的发展而发展。 它会改善。

这个特定的行:

client.action('book', 'create', { 'name': 'My Awesome Book' });

对查询字符串使用相同的字典,请求正文不是很好。 我猜这是抽象泄漏。 你真的想手动构建这个请求,在不同的地方指定查询参数和正文。

这目前不是我们可以在这里解决的任何问题。 不过再次感谢您的报告。

此页面是否有帮助?
0 / 5 - 0 等级