Django RESTフレームワークPOSTネストオブジェクト

です:

Django Rest Frameworkで少し問題に直面しています入れ子になったオブジェクトを含むオブジェクトを投稿しようとしています。

ここに私がありますserializers.py

class ClassSerializer(serializers.ModelSerializer):
    class Meta:
        model = Class
        fields = ('number', 'letter')


class SubjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Subject
        fields = ('title',)


class ExamSerializer(serializers.ModelSerializer):
    subject = SubjectSerializer()
    clazz = ClassSerializer()

    class Meta:
        model = Exam
        fields = ('id', 'subject', 'clazz', 'topic', 'date', 'details')
        depth = 1

    def create(self, validated_data):
        return Exam.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.__dict__.update(**validated_data)
        instance.save()

        return instance

そしてcreate()からviews.py

def create(self, request):
    serializer = self.serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)
    self.perform_create(serializer)

    return Response(serializer.validated_data, status=status.HTTP_201_CREATED)

そして、これがPostmanからの応答です。郵便配達員の応答

私はこの問題についてここでいくつかの投稿を読みましたが、それでもそれで立ち往生しています。私はいくつかの方法でそれを修正しようとしましたが、それはまだ戻ってきてい"This field is required."ます。

アレクシハクリ:

ネストされたシリアル化の問題を扱っています続行する前に、リンクされたドキュメントをお読みください。

あなたの質問はDRFの問題の複雑な領域に関連しているため、シリアライザとビューセットがどのように機能するかを理解するには、いくつかの説明と議論が必要です。

異なるHTTPメソッドに異なるデータ表現を使用して、同じエンドポイントを介しSubjectClassデータを表現する問題について説明します。これは、データをネストされた形式で表現したい場合に一般的に問題になるためです。たとえば、ドロップダウンセレクターなどを使用して、ユーザーインターフェイスにクリーンな使用に十分な情報を提供したいと考えています。

デフォルトでは、DjangoとDjango REST Framework(DRF)は、関連するオブジェクト(your SubjectClass)を主キーで参照しますデフォルトでは、これらはDjangoの自動インクリメント整数キーです。他の方法でそれらを参照したい場合は、これを上書きする必要があります。いくつかの異なるオプションがあります。

  1. 最初のオプションは、作成と更新のロジック特化することです。他の属性を介してクラスを参照し、手動で作成用のルックアップを書き込むか、参照しているキーをクラスのプライマリキーとして設定します。一意の単一フィールドである限り、クラスの名前、UUID、またはその他の属性をプライマリデータベースキーとして設定できます(これについて言及しているのは、現時点でClassモデルを調べているためです)複合(数字、文字)検索語で構成される複合検索)。createたとえば、ビューメソッド(POSTの場合)で関連オブジェクトのルックアップをオーバーライドできますが、ビューメソッド(updatePUTおよびPATCHの場合)でも同様のルックアップを処理する必要があります
  2. 2つ目は、私の意見では、オブジェクトの表現特化することをお勧めします。通常は主キーでクラスを参照し、オブジェクトを読み取るためのシリアライザを1つと、オブジェクトを作成および更新するためのシリアライザを1つ作成します。これは、シリアライザクラスの継承と表現のオーバーライドによって簡単に実現できます。POST、PUT、PATCHなどのリクエストで主キーを使用して、クラス参照と外部キーを更新します。

オプション1:作成および更新で任意の属性を使用してクラスと件名を検索します。

ネストされたクラスシリアライザーを読み取り専用に設定します。

class ExamSerializer(serializers.ModelSerializer):
    subject = SubjectSerializer(read_only=True)
    clazz = ClassSerializer(read_only=True)

ビューのcreateをオーバーライドして、自由形式の属性で関連クラスを検索します。また、DRFがmixinでこれを実装する方法も確認してくださいupdateこれらを正しく処理するには、メソッドをオーバーライドする必要があります。また、この方法をとる場合はPATCHPUT(更新)に加えて部分更新)サポートも考慮する必要があります。

def create(self, request):
    # Look up objects by arbitrary attributes.
    # You can check here if your students are participating
    # the classes and have taken the subjects they sign up for.
    subject = get_object_or_404(Subject, title=request.data.get('subject'))
    clazz = get_object_or_404(
        Class, 
        number=request.data.get('clazz_number')
        letter=request.data.get('clazz_letter')
    )

    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    serializer.save(clazz=clazz, subject=subject)
    headers = self.get_success_headers(serializer.data)

    return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

オプション2:シリアライザを読み取りと書き込みに特化し、主キーを使用します。これは慣用的なアプローチです:

最初に、通常の操作(POST、PUT、PATCH)に使用するデフォルトのModelSerializerを定義します。

class ExamSerializer(serializers.ModelSerializer)
    class Meta:
        model = Exam
        fields = ('id', 'subject', 'clazz', 'topic', 'date', 'details')

次に、必要なフィールドを、データを読み取るためにそれらに与えたい種類の表現で上書きします(GET):

class ExamReadSerializer(ExamSerializer):
     subject = SubjectSerializer(read_only=True)
     clazz = ClassSerializer(read_only=True)

次に、ViewSetのさまざまな操作に使用するシリアライザを指定します。ここでは、読み取り操作のネストされたSubjectおよびClassデータを返しますが、更新操作には主キーのみを使用します(はるかに簡単です)。

class ExamViewSet(viewsets.ModelViewSet):
     queryset = Exam.objects.all()

     def get_serializer_class(self):
         # Define your HTTP method-to-serializer mapping freely.
         # This also works with CoreAPI and Swagger documentation,
         # which produces clean and readable API documentation,
         # so I have chosen to believe this is the way the
         # Django REST Framework author intended things to work:
         if self.request.method in ['GET']:
             # Since the ReadSerializer does nested lookups
             # in multiple tables, only use it when necessary
             return ExamReadSerializer
         return ExamSerializer

ご覧のとおり、オプション2はDRF(get_serializer_class実装)の上に手書きのコードを3行しか含まないため、それほど複雑ではなくエラーが発生しやすいようです。フレームワークのロジックにオブジェクトの表現と作成および更新を理解させるだけです。

私は他にも多くのアプローチを見てきましたが、これまでのところ、私のために維持するコードが最も少なく、DRFの設計をクリーンな方法で活用しているアプローチです。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Django RESTフレームワーク:さまざまなserizalizedオブジェクトのリスト?

Django RESTフレームワーク:ネストされたJSONを多くのオブジェクトにフラット化

Django Restフレームワーク:1つのPOSTリクエストに複数のオブジェクトを挿入します

django RESTフレームワークでネストされたオブジェクトを設定するにはどうすればよいですか?

djangoのRESTフレームワークにオブジェクトの配列を投稿する方法は?

Django RESTフレームワーク:AttributeError:Serializerオブジェクトに属性 'Meta'がありません

Django RESTフレームワーク-get_queryset: 'MyModel'オブジェクトに属性 'model'がありません

Django RESTフレームワーク: 'BasePermissionMetaclass'オブジェクトは反復可能ではありません

Django RESTフレームワーク:AttributeError: 'DeferredAttribute'オブジェクトに属性 'isoformat'がありません

Django-Rest-モデルオブジェクトと画像を返すフレームワークAPIView

django restフレームワークを使用して、既存の親オブジェクトに新しいネストされた子オブジェクトを追加する方法

django restフレームワークエラーユニットテスト:TypeError:タイプ 'type'のオブジェクトにlen()がありません

Django RESTフレームワーク:オブジェクトへのユーザーアクセスを制限する

Django RESTフレームワーク:ネストされたオブジェクトの最新のもののみを表示し、ネストされていないJSONとして返します

django restフレームワークでオブジェクトを作成するときに、ネストされたシリアライザーのシリアライザーにユーザーデータを渡します

Django RESTフレームワーク:AttributeError: 'ユーザー'オブジェクトに属性 'ブック'がありません

Django RESTフレームワークのGETネストされたシリアライザーはエラーを生成します: 'RelatedManager'オブジェクトには属性がありません 'datafile_set' "

Django RESTフレームワークのカスタムSerializerフィールド内のリクエストオブジェクトにアクセスするにはどうすればよいですか?

django RESTフレームワーク "TypeError: 'type'オブジェクトは反復可能ではありません"エラー

Django RESTフレームワークシリアライザーPrimaryKeyRelatedField()がGET応答にオブジェクトを追加しない

Django RESTフレームワークシリアライザー:逆の関係の最新のオブジェクトを表示します

Djangoフレームワーク:「UserView」オブジェクトには属性がありません「object」

Django RESTフレームワーク:タイプオブジェクトXには属性 'get_extra_actions'がありません

Django RESTフレームワーク-MultiSelectField-TypeError:タイプ 'set'のオブジェクトはJSONシリアル化可能ではありません

djangoレストフレームワークで複数のオブジェクトを更新するにはどうすればよいですか?

AttributeError: 'QuerySet'オブジェクトにDjangoレストフレームワークの属性 'active'がありません

/ 'OrderedDict'オブジェクトのAttributeErrorには、クイックスタートドキュメントのDjango RESTフレームワークに属性 'register'がありません

DjangoテストのRESTフレームワーク:APIRequestFactoryとAPIClient

django RESTフレームワーク-ネストされたModelSerializerの限定されたクエリセット?

TOP 一覧

  1. 1

    セレンのモデルダイアログからテキストを抽出するにはどうすればよいですか?

  2. 2

    Ansibleで複数行のシェルスクリプトを実行する方法

  3. 3

    tkinterウィンドウを閉じてもPythonプログラムが終了しない

  4. 4

    Windows 10 Pro 1709を1803、1809、または1903に更新しますか?

  5. 5

    Crashlytics:コンパイラー生成とはどういう意味ですか?

  6. 6

    GoDaddyでのCKEditorとKCfinderの画像プレビュー

  7. 7

    パンダは異なる名前の列に追加します

  8. 8

    モーダルダイアログを自動的に閉じる-サーバーコードが完了したら、Googleスプレッドシートのダイアログを閉じます

  9. 9

    グラフ(.PNG)ファイルをエクスポートするZabbix

  10. 10

    Chromeウェブアプリのウェブビューの高さの問題

  11. 11

    ラベルとエントリがpythontkinterに表示されないのはなぜですか?

  12. 12

    Windows 10の起動時間:以前は20秒でしたが、現在は6〜8倍になっています

  13. 13

    mutate_allとifelseを組み合わせるにはどうすればよいですか

  14. 14

    Reactでclsxを使用する方法

  15. 15

    ネットワークグラフで、ネットワークコンポーネントにカーソルを合わせたときに、それらを強調表示するにはどうすればよいですか?

  16. 16

    テキストフィールドの値に基づいて UIslider を移動します

  17. 17

    ファイル内の2つのマーカー間のテキストを、別のファイルのテキストのセクションに置き換えるにはどうすればよいですか?

  18. 18

    MLでのデータ前処理の背後にある直感

  19. 19

    Unity:未知のスクリプトをGameObject(カスタムエディター)に動的にアタッチする方法

  20. 20

    Pythonを使用して同じ列の同じ値の間の時差を取得する方法

  21. 21

    グラフからテーブルに条件付き書式を適用するにはどうすればよいですか?

ホットタグ

アーカイブ