Django-filter: フィルタフィールドは、すべてのDRFビューアクションで技術的に許可されています。 これはCoreAPIスキーマを台無しにします。

作成日 2018年05月16日  ·  3コメント  ·  ソース: carltongibson/django-filter

DRFとDjangoFilterBackendを有効にしてCoreAPIを使用する場合、クライアントは、create、update、またはpartial_updateアクションのすべてのフィールドをクエリパラメーターにもマップしようとします。 これにより、これらのメソッドを使用するクライアントの機能が損なわれます。

名前を使用して本を作成しようとするリクエストがあり、名前もモデルのフィルター可能なフィールドである場合:

# 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のバグであり、リクエストを作成するときにクエリ文字列パラメーターとリクエスト本文を適切に区別していないということです。

一般に、安全でないアクションのフィルタリングを無効にするだけでは正しくありません。 フィルタリングは、更新が行われる基本クエリセットを確立するときに発生します。

考えてみるために、今はこれを開いたままにしておきます。

また、これはクライアントの問題だと思いますが、考えれば考えるほど、書き込みクエリ(特に特定のリソースへの書き込み)ではアクションが実際には意味をなさないように感じます。また、スキーマは意味をなさないはずです。使用しない場合は、これらのフィールドを用意してください。

迅速な返信をありがとうございます。私はあなたの考えがこれについてどうなっているのか非常に興味があります。

多かれ少なかれ、私たちはここで、(現在の状態で)技術を凌駕する_automagic_コード生成に対する私たちの願望によって制限されていると思います。

スキーマ(利用可能な形式のいずれか)では(まだ)できないことがたくさんあります。たとえば、CoreAPIでは、日付範囲フィルターにパラメーターをグループ化して表示することはまだできません。それらが関連していること。 (手作業でスキーマを作成できることはにもたくさんありますが、もちろん、誰もそれを望んでいません。)

しかし、それは進化し、それが進むにつれてツールも進化します。 良くなります。

この特定の行:

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

両方のクエリ文字列に同じdictを使用し、リクエストの本文は適切ではありません。 抽象化が漏れていると思います。 クエリパラメータと本文を別々の場所で指定して、このリクエストを_手作業で_作成する必要があります。

これは現在、ここで対処できるものではありません。 でも、報告してくれてありがとう。

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