如何在 Django-Filter 和 Django REST Framework 中设置 `filterset_fields`?

问题描述 投票:0回答:2

当我像下面这样设置 fiterset_fields 时,

class SubCategoryViewSet(viewsets.ReadOnlyModelViewSet):
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["category_id"] # single underscore

当具有指定 ID 的类别不存在时,我会收到此响应

{
    "category_id": [
        "Select a valid choice. That choice is not one of the available choices."
    ]
}

但是当我把它设置成这样

class SubCategoryViewSet(viewsets.ReadOnlyModelViewSet):
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["category__id"] # notice the double underscore

当具有指定 ID 的类别不存在时,我得到一个

[]

为什么会这样? 这样做的正确方法是什么?

python django django-rest-framework django-filter
2个回答
1
投票

先看看它们的区别

案例一

你正在定义一个

category_id
字段用于过滤,而django假设
category_id
是Model的一个字段。此处的视图集期望
category_id
字段出现在请求中,并包含可用选项中的有效选项。否则会产生错误。

案例二

您正在定义一个

category__id
字段用于过滤,django 假设类别模型有一个名为
id
的字段将用于过滤目的。它根据 Category 模型中的 id 属性过滤结果,如果结果集为空,则返回空列表 []。注意:推荐使用这种方法,因为它提供了灵活性。


0
投票

为什么会这样?这样做的正确方法是什么?

这部分是 Django 的局限性之一。如果你使用一个字段名,比如

category_id
,是一个,它会首先检索一个collection if distinct值。如果输入的值不在其中,那么它可以引发异常。

但是,如果你使用 JOIN,就像

category__id
的情况一样,你加入一个额外的模型,这个技巧显然没有实现。这样做可能是可行的,尽管对于多个 JOIN 来说这可能很棘手,特别是如果有一些其他过滤活动过滤另一个部分重叠的 JOIN。因此,由于在这种情况下 Django 无法派生出一组唯一的值,因此它会返回一个空列表。

我建议使用第一个,所以

category_id
。事实上,如果有人输入了一个错误的
category_id
,那么说
category_id
不存在而不是返回一个空列表会提供更多的信息。在后一种情况下,它给人的印象是该类别存在,但根本没有该类别的子类别。通常提供更多信息更好,当然如果它不是“敏感的”。

© www.soinside.com 2019 - 2024. All rights reserved.