Django-filter: 如果 FilterSet 中没有给出字段,则引发异常

创建于 2016-09-28  ·  11评论  ·  资料来源: carltongibson/django-filter

class BooksFilter(filters.FilterSet):
    class Meta:
        model = Books

当在过滤器集类中省略fields选项时(如上),所有模型字段都将包含在过滤器集中。 当与 DRF 结合使用时,这可能会导致信息泄漏,其中表单在可浏览的 API 中呈现。

由于潜在的安全问题,Django 和 DRF 都需要在表单/序列化程序中明确指定字段。 这在 django-filter 过滤器集中也应该是必需的。
http://www.django-rest-framework.org/api-guide/serializers/#specifying -which-fields-to-include
https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#selecting -the-fields-to-use

如果需要,我很乐意提供 PR 或解释更多关于在哪些情况下这会导致信息泄露的信息。

ImprovemenFeature

最有用的评论

顺便说一句 - #451 部分解决了数据泄漏问题。 现在,您应该会看到有关未定义/更改行为的弃用警告。 在 1.0 中,新的行为是缺席的Meta.fieldsMeta.fields = None什么都不做。

所有11条评论

@nip3o 是的。 很高兴看到这个。

我还希望字段需要声明的过滤器,根据 DRF,当你在它的时候......😉

顺便说一句 - #451 部分解决了数据泄漏问题。 现在,您应该会看到有关未定义/更改行为的弃用警告。 在 1.0 中,新的行为是缺席的Meta.fieldsMeta.fields = None什么都不做。

我还希望字段需要声明的过滤器,根据 DRF,当你在它的时候

我不确定这将如何与Meta.fields的 dict 语法一起使用。 例如:

class UserFilter(filters.FilterSet):
    username = filters.CharFilter()

    class Meta:
        model = User
        fields = {
            'name': ['contains', 'startswith', 'endswith', ...'],
            ???
        }

我不确定这将如何与 dict 语法一起使用

确实。

我仍然有点 :-1: 对此。 我看不到用声明的过滤器解决Meta.fields dict 语法的方法。 至少,不是以一种不尴尬的方式:

class UserFilter(filters.FilterSet):
    username = filters.CharFilter(name='username', lookup_expr='exact')
    username_like = filters.CharFilter(name='username', lookup_expr='icontains')
    relevance = filters.CharFilter(method='filter_relevance')

    class Meta:
        model = User
        fields = {
            'name': ['contains', 'startswith', 'endswith', ...'],
            'username': ['exact'],  # match w/ the lookup_expr? 
            'username_like': ['icontains'],
            'relevance': [???]  # What about method filters?
        }

此外,对于不继承FilterSet.FILTER_DEFAULTS中的字段类的自定义模型字段,此要求会遇到问题。 自定义字段将需要以下内容:

class NetworkSettingFilter(FilterSet):
    mask = MaskFilter(...)

    class Meta:
        model = NetworkSetting
        fields = ['mask']
        filter_overrides = {
            SubnetMaskField: {'filter_class': MaskFilter},
        }

# vs.

class NetworkSettingFilter(FilterSet):
    mask = MaskFilter(...)

    class Meta:
        model = NetworkSetting

旁注:后一点是我们_可以_修复的。 我们必须重写自动生成来表现得像 DRF 的序列化器,而不是像 Django 的模型表单。 无论哪种方式,我主要关心的是语法冲突。

好的。 让我们暂时搁置它。

我喜欢原来的提议。 我倾向于将其范围限定为 _If fields是一个列表..._ 但我需要多考虑一下。

有点来回,但我要重新定义这个只是为了原来的问题

应该声明fieldsexcludefields = '__all__'应该是最小值。

(不强制列表匹配是我们可以回到的。)

相关的 DRF 代码在这里

        assert not (fields is None and exclude is None), (
            "Creating a ModelSerializer without either the 'fields' attribute "
            "or the 'exclude' attribute has been deprecated since 3.3.0, "
            "and is now disallowed. Add an explicit fields = '__all__' to the "
            "{serializer_class} serializer.".format(
                serializer_class=self.__class__.__name__
            ),
        )

我们需要filters_for_model中添加类似的内容:

    # Setting exclude with no fields implies all other fields.
    if exclude is not None and fields is None:
        fields = ALL_FIELDS

它需要被弃用才能开始。

应该声明fieldsexcludefields = '__all__'应该是最小值。

我绝对可以落后。 目前正在做PR。

凉爽的。

想一想,不用担心贬值。 这是一个很小的变化,主要版本变化。 只需确保在更改说明中注明即可。 👍🏽

想一想,不用担心贬值。 这是一个很小的变化,主要版本变化。 只需确保在更改说明中注明即可。

意图稍有不同,但我们实际上在这里涵盖了这一点。

此外,目前正在重构filters_for_model以不尝试为声明的过滤器生成过滤器。 (这与fields = ['mask']会引发不必要的异常的子网/掩码示例相关。

由 #550 关闭

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

相关问题

GuillaumeCisco picture GuillaumeCisco  ·  3评论

jwineinger picture jwineinger  ·  3评论

xtrinch picture xtrinch  ·  4评论

lalzada picture lalzada  ·  3评论

edmorley picture edmorley  ·  3评论