partial_update
を Django Rest Framework で実装しようとしていますが、行き詰まっているので、明確にする必要があります。
partial = Trueを指定する必要があるのはなぜですか?
私の理解では、partial_update
メソッド内のDemoオブジェクトを簡単に更新できました。これの目的は何ですか?
シリアル化された変数の内部には何がありますか?partial_update
メソッドのserialized
変数の内部には何がありますか?それはデモオブジェクトですか?背後でどの関数が呼び出されますか?
ビューセット
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
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/
誰もまだこれを指摘していないようですので、簡単なメモ:
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を呼び出し、現在のユーザーと既に更新されたデモインスタンスを渡すことを他のことを行います。
お役に立てれば。
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)