多くのフィールドを持つモデル「MyModel」があり、PATCHメソッドを使用してフィールド「status」を更新したいと思います。クラスベースのビューを使用しています。 PATCHを実装する方法はありますか?
シリアライザーでは、 partial=True
シリアライザーを初期化するとき。これが PATCH
リクエストの処理方法 デフォルトで 汎用ビューで です。
serializer = CommentSerializer(comment, data=request.data, partial=True)
これにより、標準のPUT
リクエストの制限なしに、シリアライザーの個々のフィールド、または必要に応じてすべてのフィールドを更新できます。
Kevin Brown が述べたように、 chefarov がうまく明確になったpartial=True
を使用できます。
修正したいのですが、使用しているHTTPメソッドに応じて、ジェネリックを自由に使用できると言います。
要求されたようなPATCH HTTPメソッドを使用している場合は、そのまま使用できます。 partial_update
のUpdateModelMixin
コードを見ることができます:
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)
PATCHとは異なるHTTPメソッドの場合、次のようにget_serializer
メソッドをオーバーライドするだけでこれを実現できます。
def get_serializer(self, *args, **kwargs):
kwargs['partial'] = True
return super(YOUR_CLASS, self).get_serializer(*args, **kwargs)
これにより、シリアライザーが部分的に作成され、残りのジェネリックは、update/partial_updateメカニズムに手動で介入することなく、チャームのように機能します。
フードの下
私はジェネリックを使用しました:generics.UpdateAPIView
このコードを持つUpdateModelMixin
を使用します:
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
…
そのため、get_serializer
関数をオーバーライドする場合、実際に部分引数をオーバーライドして、強制的にtrueにすることができます。
一部のHTTPメソッドに対してのみ部分的にしたい場合、このアプローチはより困難になることに注意してください。
私はdjangorestframework == 3.5.3を使用しています
すぐにサポートされるようです。ブラウザーAPIで、モデルの詳細ページに移動し、HTML Form
タブの横にあるRaw data
をクリックして、IDフィールドと変更するフィールドを除くすべてをJSON文字列から削除します。 PATCH
をクリックします。部分的なPATCH
更新が実行されます。
私はdjangorestframework==3.2.4
を使用しており、これを有効にするためにViewSetとSerializerに何もする必要はありません。
この例では、モデルのbool status_field
フィールドを更新しており、jquery 2.2.1を使用しています。以下を<head>
に追加します。
<script src="{% static 'my_app/jquery.min.js' %}"></script>
<script>
$(document).ready(function(){
var chk_status_field = $('#status_field');
chk_status_field.click(function(){
$.ajax({url: "{% url 'model-detail' your_rendering_context.id %}",
type: 'PATCH', timeout: 3000, data: { status_field: this.checked }
})
.fail(function(){
alert('Error updating this model instance.');
chk_status_field.prop('checked', !chk_status_field.prop('checked'));
});
});
});
</script>
次に<form>
で:
<input type="checkbox" id="status_field" {% if your_rendering_context.status_field %}
checked {% endif %} >
チェックボックスの変更を許可し、失敗した場合は元に戻すことを選択しました。しかし、click
をmousedown
に置き換えて、AJAX呼び出しが成功した場合にのみチェックボックスの値を更新することができます。ただし、接続が遅い場合。
ビューの多くを変更せずにModelSerializer
を使用して簡単なソリューションを探している場合は、ModelSerializer
をサブクラス化して、すべてのModelSerializer
sを継承させることができます。
class PatchModelSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
kwargs['partial'] = True
super(PatchModelSerializer, self).__init__(*args, **kwargs)
class ArticleSerializer(PatchModelSerializer):
class Meta:
model = Article
私はしばらくこれに苦労しましたが、これは汎用ビューまたは汎用ビューとミックスインの組み合わせを使用した非常に簡単な実装です。
汎用更新ビュー(generics.UpdateAPIView)を使用する場合は、次のコードを使用して、リクエストタイプがPATCHであることを確認してください。
class UpdateUser(generics.UpdateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
他に何もありません!
更新ミックスイン(mixins.UpdateModelMixin)を汎用ビュー(generics.GenericAPIView)と組み合わせて使用している場合は、次のコードを使用して、リクエストタイプがPATCHであることを確認してください。
class ActivateUser(mixins.UpdateModelMixin, generics.GenericAPIView):
serializer_class = UserSerializer
model = User
lookup_field = 'email'
def get_queryset(self):
queryset = self.model.objects.filter(active=False)
return queryset
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
2番目の例はより複雑で、クエリセットとルックアップフィールドをオーバーライドする方法を示していますが、注意が必要なコードはパッチ関数です。