ホーム>source

キー serializer.data['test'] = 'asdf' を追加しようとしました 、これは何もしないようです。

キーの値の表現を変換したい。これを行うために、値を使用して新しい値を計算し、辞書の古い値を置き換えようとしています。

これは私が達成したいことですが、値が置き換えられない理由がわかりません。エラーは発生せず、結果の辞書には、私が何かを置き換えようとしたという証拠はありません。

<前>ウィズウィズ

ターミナル: class PlaceDetail(APIView): def get(self, request, pk, format=None): place = Place.objects.select_related().get(pk=pk) serializer = PlaceSerializer(place) #serializer.data['tags'] = pivot_tags(serializer.data['tags']) serializer.data['test'] = 'asdf' print(serializer.data['test']) return Response(serializer.data)

私はその KeyError: 'test' を印刷して観察しました辞書です。

また、使用しようとしている構文が機能することをテストしました。

<前>ウィズウィズ

serializer.data を適切に変更する方法辞書?

>>> test = {'a': 'Alpha'} >>> test {'a': 'Alpha'} >>> test['a'] 'Alpha' >>> test['a'] = 'asdf' >>> test {'a': 'asdf'}
あなたの答え
  • 解決した方法 # 1

    ウィズウィズ  プロパティはw​​yzwyzを返します  これは Serializer.data を使用して構築されます 。戻り値は OrderedDict ではありません  自体。

    したがって、 serializer._data の戻り値を変更する   serializer._data を変更しません  メンバー。結果として、次の serializer.data の呼び出し  変更されません。

    ウィズウィズ
    

    serializer._data の戻り値のコピーを保持できます 、これは順序付けられた辞書であり、必要に応じてそれを操作します。

    例:

    <前>ウィズウィズ

    なぜ:

    Django Restframeworkのソースコードを見ると、それが serializer.data に表示されます。  クラス、

    ウィズウィズ  通常の辞書です。

    ウィズウィズ  プロパティのように振る舞うように装飾されたメソッドです。 # In class Serializer(BaseSerializer) @property def data(self): ret = super(Serializer, self).data return ReturnDict(ret, serializer=self) # In class ReturnDict(OrderedDict) def __init__(self, *args, **kwargs): self.serializer = kwargs.pop('serializer') super(ReturnDict, self).__init__(*args, **kwargs) を返します   serializer.data から派生したカスタマイズされたクラスであるオブジェクト 。返された # keep the return value of serializer.data serialized_data = serializer.data # Manipulate it as you wish serialized_data['test'] = 'I am cute' # Return the manipulated dict return Response(serialized_data)  オブジェクトは Serializer のキーと値のペアを使用して初期化されます 。

    Serializer._data の場合   Serializer.data を返します  直接、元の方法は期待どおりに機能します。しかし、それは ReturnDict を使用して構築された別の辞書のようなオブジェクトを返すため、機能しません 。

    OrderedDict の戻り値は   ReturnDict ではない 、しかし順序付けられた辞書のようなオブジェクト。戻り値を操作しても Serializer._data は変更されません 。

    なぜ Serializer.data なのか   Serializer._data を返さない  直接は、データの誤った変更を回避し、 Serializer._data のかなりの表現を返すことです 。

  • 解決した方法 # 2

    表現を明示的に上書きするのではなく、SerializerMethodFieldを使用する必要があります。

  • 解決した方法 # 3

    @yuwangの答えにさらに基づいて、私は Serializer.data を使用しました  シリアライザの特定のフィールドの値を変更します。次に例を示します。

    変更したいフィールド、それを Serializer._data としましょう 。このフィールドは Serializer._data としてDjangoモデルに存在します  したがって、シリアライザ定義のフィールドのリストには存在せず、単に serializer.data で言及されていました  シリアライザ定義内の定義。

    だからここに私のコードが前にどのように見えたかです:

    <前>ウィズウィズ

    上記の結果、フィールド serializer._data の値   serializer._data のレコードの値に基づいて常にフェッチされました  オブジェクト。ただし、テスト目的のために、開発段階でこのフィールドの値をFalseとして返したいため、コードを次のように変更しました。

    <前>ウィズウィズ

    上記のコードが入力されると、API呼び出しは常にシリアライザフィールド SerializerMethodField の値を返しました  Falseとして。

    is_modifyable

関連記事

  • 前へ java - JPAクエリ:サブクエリをグループ化条件に結合する
  • 次へ javascript - 背景をクリックしたときにモーダルが閉じないようにする[Vuejs]