1. ホーム
  2. django

[解決済み] Django Rest フレームワーク。フィールドのサブセットを動的に返す

2022-08-13 22:27:24

質問

問題点

ブログ記事で推奨されているように 実用的なRESTful APIを設計するためのベストプラクティス を追加したいと思います。 fields クエリパラメータを Django Rest Framework ベースの API に追加したいのですが、これによってユーザはリソースごとにフィールドのサブセットのみを選択することができます。

シリアライザーです。

class IdentitySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Identity
        fields = ('id', 'url', 'type', 'data')

通常のクエリでは、すべてのフィールドが返されます。

GET /identities/

[
  {
    "id": 1,
    "url": "http://localhost:8000/api/identities/1/",
    "type": 5,
    "data": "John Doe"
  },
  ...
]

クエリに fields パラメータは、フィールドのサブセットのみを返すべきです。

GET /identities/?fields=id,data

[
  {
    "id": 1,
    "data": "John Doe"
  },
  ...
]

無効なフィールドを持つクエリは、無効なフィールドを無視するか、クライアントエラーを投げる必要があります。

目標

これはどうにかして箱から出しても可能なのでしょうか?そうでない場合、これを実装する最も簡単な方法は何でしょうか?これを行うサード パーティのパッケージはすでにあるのでしょうか?

どのように解決するのですか?

シリアライザーをオーバーライドすることができます __init__ メソッドをオーバーライドして fields 属性を動的に設定します。メソッドにアクセスすることができます。 request オブジェクトにアクセスできます。

以下は、以下のコピー&ペーストです。 Django Rest Framework ドキュメントの例 を参照してください。

from rest_framework import serializers

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    """
    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        fields = self.context['request'].query_params.get('fields')
        if fields:
            fields = fields.split(',')
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)


class UserSerializer(DynamicFieldsModelSerializer, serializers.HyperlinkedModelSerializer):

    class Meta:
        model = User
        fields = ('url', 'username', 'email')