web-dev-qa-db-ja.com

Django Rest Frameworkの部分的な更新

partial_updateDjango Rest Framework で実装しようとしていますが、行き詰まっているので、明確にする必要があります。

  1. partial = Trueを指定する必要があるのはなぜですか?
    私の理解では、partial_updateメソッド内のDemoオブジェクトを簡単に更新できました。これの目的は何ですか?

  2. シリアル化された変数の内部には何がありますか?
    partial_updateメソッドのserialized変数の内部には何がありますか?それはデモオブジェクトですか?背後でどの関数が呼び出されますか?

  3. ここで実装をどのように終了しますか?

ビューセット

class DemoViewSet(viewsets.ModelViewSet):
    serializer_class = DemoSerializer

    def partial_update(self, request, pk=None):
        serialized = DemoSerializer(request.user, data=request.data, partial=True)
        return Response(status=status.HTTP_202_ACCEPTED)

シリアライザー

class DemoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Demo
        fields = '__all__'

    def update(self, instance, validated_data):
        print 'this - here'
        demo = Demo.objects.get(pk=instance.id)
        Demo.objects.filter(pk=instance.id)\
                           .update(**validated_data)
        return demo
41
intelis

Forpartial update-PATCH httpメソッド

Forfull update-PUT httpメソッド

DRFで更新を行う場合、すべての(必須)フィールドの値を含む要求データを送信することになっています。これは、少なくともリクエストがPUT httpメソッドを介している場合に当てはまります。私が理解したことから、あなたは1つまたは少なくともすべてではないモデルインスタンスフィールドを更新したいと考えています。この場合、PATCH httpメソッドでリクエストを作成します。 Django restフレームワーク(DRF)はそのまま使用できます。

例(トークン認証あり):

curl -i -X PATCH -d '{"name":"my favorite banana"}' -H "Content-Type: application/json" -H 'Authorization: Token <some token>'  http://localhost:8000/bananas/
29
Gooshan

誰もまだこれを指摘していないようですので、簡単なメモ:

serialized = DemoSerializer(request.user, data=request.data, partial=True)

DemoSerializerの最初の引数は、ユーザーではなくDemoインスタンスである必要があります(少なくとも私のようなDRF 3.6.2を使用している場合)。

あなたが何をしようとしているのかわかりませんが、これは実例です:

def partial_update(self, request, *args, **kwargs):
    response_with_updated_instance = super(DemoViewSet, self).partial_update(request, *args, **kwargs)
    Demo.objects.my_func(request.user, self.get_object())
    return response_with_updated_instance

部分的な更新を行ってから、my_funcを呼び出し、現在のユーザーと既に更新されたデモインスタンスを渡すことを他のことを行います。

お役に立てれば。

1

Rest_frameworkシリアライザーでのマルチ属性/フィールド検証がPOST/resources /リクエストで機能していましたが、PATCH/resources /リクエストで失敗するという問題がありました。 PATCHケースでは、指定されたattrs dictの値のみを探し、self.instanceの値にフォールバックしないため、失敗しました。そのフォールバックを行うメソッドget_attr_or_defaultを追加するとうまくいったようです:

class EmailSerializer(serializers.ModelSerializer):

    def get_attr_or_default(self, attr, attrs, default=''):
        """Return the value of key ``attr`` in the dict ``attrs``; if that is
        not present, return the value of the attribute ``attr`` in
        ``self.instance``; otherwise return ``default``.
        """
        return attrs.get(attr, getattr(self.instance, attr, ''))

    def validate(self, attrs):
        """Ensure that either a) there is a body or b) there is a valid template
        reference and template context.
        """
        existing_body = self.get_attr_or_default('body', attrs).strip()
        if existing_body:
            return attrs
        template = self.get_attr_or_default('template', attrs)
        templatecontext = self.get_attr_or_default('templatecontext', attrs)
        if template and templatecontext:
            try:
                render_template(template.data, templatecontext)
                return attrs
            except TemplateRendererException as err:
                raise serializers.ValidationError(str(err))
        raise serializers.ValidationError(NO_BODY_OR_TEMPLATE_ERROR_MSG)
0
jrwdunham