やりたかったこと
REST API を作成してクライアントから ajax で実行しようとした。
GET や POST は問題なく実行できたが、同じように DELETE メソッドを実装したらエラーになってしまった。
エラーになったコード
views.py
class Books(generic.View):
def delete(self, request, *args, **kwargs):
user_id = self.request.user.id
book_id = request.GET.get('book_id')
Book.objects.filter(user_id=user_id, book_id=book_id).delete()
return JsonResponse({'message': 'Success'})
book.js
$.ajax({
url: '/books',
type: 'DELETE',
data: JSON.stringify({
"book_id" : 1,
'csrfmiddlewaretoken': 'xxxxx',
}),
dataType: 'json',
success: function(response) {
// 正常終了時の処理
},
error: function(xhr, status, error) {
// エラー時の処理
}
});
エラー ログ
[WARNING] yyyy-mm-dd 00:00:00,000 django.security.csrf.log_response:241 Forbidden (CSRF token missing.): /books
解消したコード
以下がエラーを解消したコード
変更箇所を赤文字にしています。
views.py
class Books(generic.View):
def delete(self, request, *args, **kwargs):
user_id = self.request.user.id
request_data = json.loads(self.request.body)
book_id = request_data.get('book_id')
Book.objects.filter(user_id=user_id, book_id=book_id).delete()
return JsonResponse({'message': 'Success'})
book.js
$.ajax({
url: '/books',
type: 'DELETE',
data: JSON.stringify({
"book_id" : 1
}),
headers: {
'X-CSRFToken': 'xxxxx'
},
dataType: 'json',
success: function(response) {
// 正常終了時の処理
},
error: function(xhr, status, error) {
// エラー時の処理
}
});
まとめ
要するにCSRF トークンをヘッダに設定してあげる必要がありますよという話でした
また、クライアントから送られたデータをサーバー側で参照する方法もちょっと違いました。
コメント