Django-filter: FilterSetでフィールドが指定されていない場合は、例外を発生させます

作成日 2016年09月28日  ·  11コメント  ·  ソース: carltongibson/django-filter

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

フィルタセットクラスでfieldsオプションを省略すると(上記のように)、すべてのモデルフィールドがフィルタセットに含まれます。 これは、フォームが閲覧可能なAPIでレンダリングされるDRFと組み合わせて使用​​すると、情報漏えいにつながる可能性があります。

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.fieldsまたはMeta.fields = Noneがない場合は何も実行されません。

全てのコメント11件

@ nip3oうん。 これを見て幸せです。

また、DRFに従って、フィールドに宣言されたフィルターが必要ですが、その間は...😉

ところで-データ漏洩は#451によって部分的に対処されました。 現在、未定義/変更された動作に関する非推奨の警告が表示されるはずです。 1.0では、新しい動作として、 Meta.fieldsまたはMeta.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

補足:この後の点は、私たちが修正できるものです。 Djangoのモデル形式ではなく、DRFのシリアライザーのように動作するように、自動生成を書き直す必要があります。 いずれにせよ、私の主な関心事は構文の矛盾です。

わかった。 とりあえずそのままにしておきましょう。

私は元の提案が好きです。 私はそれを_ fieldsがリストである場合..._にスコープする傾向がありますが、もう少し考える必要があります。

少し前後しますが、元の問題のためだけにこれを再マイルストーンします。

fieldsまたはexcludeのいずれかを宣言する必要があります。 fields = '__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

開始するには非推奨にする必要があります。

fieldsまたはexcludeのいずれかを宣言する必要があります。 fields = '__all__'が最小である必要があります。

私は間違いなくそれを後回しにすることができます。 現在PRに取り組んでいます。

いいね。

考えてみれば、減価償却について心配する必要はありません。 これは小さな変更であり、メジャーバージョンの変更です。 変更メモで必ずそれを呼び出してください。 👍🏽

考えてみれば、減価償却について心配する必要はありません。 これは小さな変更であり、メジャーバージョンの変更です。 変更メモで必ずそれを呼び出してください。

意図は少し異なりますが、実際にはここで説明します。

また、現在filters_for_modelをリファクタリングして、宣言されたフィルターのフィルター生成を試行しないようにしています。 (これは、 fields = ['mask']が不要な例外を発生させるサブネット/マスクの例に関連しています。

#550で閉鎖

このページは役に立ちましたか?
0 / 5 - 0 評価